> For the complete documentation index, see [llms.txt](https://izzyshop-1.gitbook.io/izzyshop-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://izzyshop-1.gitbook.io/izzyshop-docs/izzyshop-resources/izzy-illegalcleaner/overview.md).

# Overview

Scene types:

* **Shell** — qb-interior / K4MB1 interiors (apartments, motel, warehouse…)
* **MLO** — real world interiors (office, pool, yacht…)
* **Vehicle** — locked car, lockpick, pull body from the seat

Works with **ESX**, **QBCore**, or **Qbox** (`Config.Core = 'auto'`).

Props and HQ map live in a separate resource: **`izzy-illegalcleaner-stream`**.

### What you need installed

| Resource                                               | Why                                                                                                               |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| **qb-core** / **qbx\_core** / **es\_extended**         | Framework (money, identifier, player).                                                                            |
| **oxmysql** (or whatever SQL driver you set in config) | Level / XP / profile save.                                                                                        |
| **izzy-illegalcleaner-stream**                         | Toolbag, UV, bodybag, acidtub, HQ / MLO assets.                                                                   |
| **qb-interior**                                        | Shell models. [Official repo is fine](https://github.com/qbcore-framework/qb-interior) — no custom fork required. |
| **screenshot-basic**                                   | After photo.                                                                                                      |

Optional: **ox\_target** / **qb-target**, **ox\_lib**, vehicle keys script, police dispatch (ps-dispatch, cd\_dispatch…).

If you set `Target = 'drawtext'`, you don’t need a target resource.

### How a job works (step by step)

1. Player goes to the **dispatch** blip / NPC → target or **\[E]**.
2. NUI opens: profile, locations, party, payout %.
3. Leader picks a location → **Start Job**.
4. **Phase 0** — outfit spot → grab rag / UV / odor / bodybag from the shelf → bag.
5. **Phase 1–2** — van spawns → get in → GPS to scene → take bag from trunk.
6. **Phase 3** — crime scene (if buckets are on, the party is isolated):
   * Blood wipe minigame
   * Glass sweep
   * UV for gunpowder / traces
   * Weapon pickup
   * Corpse: search → destroy phone → bag it → load trunk
7. Odor spray (time pressure / risk).
8. After photo (`screenshot-basic`).
9. Return to depot → acid disposal or bag storage.
10. Server pays: `money/XP × (100 - risk) / 100`. On fail: fine + fail counter.

If the resource restarts, an active job can be **resumed** from the saved session.

### Install

1. Put `izzy-illegalcleaner` + `izzy-illegalcleaner-stream` in your resources folder.
2. Run `sql/install.sql`.
3. Edit `shared/config.lua` (`Language`, `Core`, `Target`…).
4. In `server.cfg`:

```cfg
ensure oxmysql
ensure qb-interior
ensure screenshot-basic
ensure izzy-illegalcleaner-stream
ensure izzy-illegalcleaner
```

**Stream first**, main script second. `ensure [izzy]` can start them in the wrong order alphabetically — prefer separate lines.

5. Restart → go to dispatch → open the panel.

### SQL

File: `sql/install.sql`

#### `izzy_cleaner_players`

| Column                           | What                               |
| -------------------------------- | ---------------------------------- |
| `identifier`                     | ESX identifier / QB-Qbox citizenid |
| `level` / `xp`                   | Rank and experience                |
| `jobs_completed` / `jobs_failed` | Stats                              |
| `total_earned` / `total_exp`     | Lifetime totals                    |
| `success_rate`                   | 0–100                              |
| `last_job_at` / `job_starts`     | Used for cooldown                  |
| `hud_layout` / `settings`        | UI prefs (JSON)                    |

#### `izzy_cleaner_jobs`

Table exists in the schema. Active party/job state mostly runs in **memory + `active_sessions.json`**; party members are not stored in SQL.

***

### `shared/config.lua` — every setting

This file is **OPEN** (outside escrow). Restart the resource after edits.

#### General

| Key                         | What it does                                                                     |
| --------------------------- | -------------------------------------------------------------------------------- |
| `Language`                  | Locale: `en`, `tr`, `de`, `fr`, `es`, `pt`, `it`, `pl`, `nl`, `ru`, `cs`, `hu`.  |
| `DebugBagPlacement`         | `true` = F8 logs for bag / trunk offsets.                                        |
| `FailJobOnMemberDisconnect` | `true` = if a party member leaves, the job fails for everyone.                   |
| `EnablePayoutShares`        | `true` = leader sets % shares in the lobby. `false` = everyone gets full payout. |
| `Core`                      | `auto` / `esx` / `qb` / `qbox`.                                                  |
| `SQL`                       | `oxmysql` / `ghmattimysql` / `mysql-async`.                                      |
| `Notify`                    | `ui` / `auto` / `ox_lib` / `qb` / `esx` / `okoknotify` / `custom`…               |
| `Target`                    | `ox_target` / `qb-target` / `drawtext`.                                          |
| `EnablePickupMarkers`       | Evidence / interaction beacons. `false` = hide them.                             |
| `VehicleKeys`               | `auto` / `esx` / `qb` / `qbx_vehiclekeys` / `custom`.                            |

#### `DrawText` (only when `Target = 'drawtext'`)

| Key        | What it does                         |
| ---------- | ------------------------------------ |
| `key`      | Control id (`38` = E).               |
| `keyLabel` | Label shown on screen.               |
| `distance` | How close before the prompt appears. |
| `text`     | Format string, e.g. `[E] Get Job`.   |

#### `DoorLockpick` (vehicle scenes)

| Key                              | What it does                                            |
| -------------------------------- | ------------------------------------------------------- |
| `enabled`                        | Turn door lockpick on/off.                              |
| `mode`                           | `auto` / `ox_lib` / `ps-ui` / `qb-lock` / `standalone`… |
| `attempts`                       | How many tries.                                         |
| `difficulty`                     | ox\_lib difficulty.                                     |
| `circles` / `time` / `timeoutMs` | Minigame parameters.                                    |
| `dispatch.enabled`               | Police alert on failed lockpick.                        |
| `dispatch.chance`                | 0–100 chance.                                           |
| `dispatch.mode`                  | `auto` / `ps-dispatch` / `cd_dispatch` / `qb`…          |
| `dispatch.policeJobs`            | Which jobs get the alert.                               |
| `dispatch.code` / `blip`         | Code and map blip.                                      |

#### `JobBlips`

Sprite / color / scale for the active-job vehicle and destination blips.

#### `Sounds`

UI / game sounds: `missionPassed`, `missionFailed`, `timerWarning`, `trunkOpen`, `trunkClose`.\
`volume` is 0.0–1.0. Each entry has `enabled`, `name`, `set`.

#### `JobOutfit`

| Key                           | What it does                                              |
| ----------------------------- | --------------------------------------------------------- |
| `enabled`                     | Require the work outfit.                                  |
| `locations`                   | Change-clothes spots (`vector4`).                         |
| `distance` / `markerDistance` | Interact / marker range.                                  |
| `changeAnim`                  | Clothing animation.                                       |
| `components`                  | Component id + drawable + texture (mask, pants, jacket…). |

#### `CorpseSearch`

| Key                     | What it does                                       |
| ----------------------- | -------------------------------------------------- |
| `enabled`               | Corpse search system.                              |
| `requiredBeforeBagging` | Must search before bagging.                        |
| `reward.enabled`        | Give a search reward.                              |
| `reward.blackMoney`     | `true` = dirty money.                              |
| `reward.moneyItem`      | `true` = inventory item, `false` = framework cash. |
| `reward.amount`         | `min` / `max`.                                     |

#### `JobLocations`

List of dispatch points. Each entry has:

* `id`, `coords` (vector4)
* `ped` — model, scenario, enabled
* `blip` — sprite, color, scale, label, shortRange
* `target` — label, icon, distance

Add as many as you want.

#### `JobVehicle`

| Key                | What it does                                    |
| ------------------ | ----------------------------------------------- |
| `model`            | Van model (`gburrito2`).                        |
| `spawnCheckRadius` | Check if spawn is clear.                        |
| `spawns`           | Spawn points to try in order.                   |
| `interiorSpawn`    | Fallback spawn on mid-job reconnect (phase 3+). |

#### `ShellDefaults`

| Key          | What it does                                                    |
| ------------ | --------------------------------------------------------------- |
| `enabled`    | Shell system. `false` = shell jobs won’t run.                   |
| `resource`   | Stream resource name (`qb-interior`). Change if you renamed it. |
| `spawnDepth` | How far below ground the shell spawns.                          |

#### `CrimeSceneBucket`

| Key       | What it does                                                   |
| --------- | -------------------------------------------------------------- |
| `enabled` | `true` = on phase 3 the party moves to its own routing bucket. |
| `id`      | Base id. Real bucket ≈ `id + partyId`.                         |

#### `JobSchedule`

| Key           | What it does                                     |
| ------------- | ------------------------------------------------ |
| `enabled`     | Time-of-day lock. Default `false`.               |
| `useGameTime` | `true` = GTA clock, `false` = real server time.  |
| `jobHours`    | `startHour` / `endHour` etc. (e.g. 21:00–06:00). |

#### `JobCooldown`

| Key                | What it does                          |
| ------------------ | ------------------------------------- |
| `enabled`          | Per-player cooldown. Default `false`. |
| `hoursBetweenJobs` | Window length in hours.               |
| `maxJobsPerWindow` | Max jobs inside that window.          |

#### `FailJobFine`

| Key       | What it does                        |
| --------- | ----------------------------------- |
| `enabled` | Take money on fail.                 |
| `mode`    | `percent` or `fixed`.               |
| `percent` | Percent of payout (e.g. 25).        |
| `amount`  | Fixed amount when `mode = 'fixed'`. |

#### `ReturnDepot`

| Key                  | What it does              |
| -------------------- | ------------------------- |
| `coords`             | Return / depot point.     |
| `bagStorage`         | Bag storage point.        |
| `bagStorageDistance` | Interact distance.        |
| `blip`               | Return blip settings.     |
| `acidDisposal`       | Acid tank disposal point. |

### `shared/locations.lua` — locations

Each location roughly has:

* `id`, `enabled`, `difficulty`, `level`
* `reward.money` / `reward.exp` (`min`–`max`)
* `timeLimit`
* Shell pool / spots / MLO / `vehicleScene` / boat settings

#### Default table

| Location            | Level | Difficulty | Money       | XP        | Type          |
| ------------------- | ----: | ---------- | ----------- | --------- | ------------- |
| Residential Murder  |     1 | easy       | 4500–5500   | 100–150   | Shell         |
| Sandy Shores Murder |     1 | easy       | 5000–6000   | 120–170   | Shell         |
| Ranch Cleanup       |     2 | medium     | 7000–8500   | 180–240   | Shell         |
| Warehouse Cleanup   |     3 | medium     | 9000–11000  | 220–300   | Shell         |
| Poolside Cleanup    |     4 | medium     | 9000–11000  | 220–300   | Outdoor / MLO |
| Office Murder       |     5 | medium     | 11000–13000 | 250–350   | MLO           |
| Vehicle Cleanup     |     8 | medium     | 7000–9000   | 200–280   | Vehicle       |
| Hotel Room          |    15 | hard       | 18000–22000 | 500–650   | Shell         |
| Yacht / Boat        |    30 | extreme    | 38000–42000 | 1200–1500 | Boat + MLO    |

Most have a **60 minute** time limit.\
Final payout uses multiplier `(100 - risk) / 100`.

Entrances: `shared/locationEntrances.lua`.\
Shell exit / models: `shared/shells.lua`.\
Detailed cleanup offsets: `data/tqdev.json`.

### Level & XP

* XP needed for next level: **`level × 1000`**\
  (1→2 = 1000, 5→6 = 5000…)
* If level is too low, the location card stays locked.
* XP / money are written to the MySQL profile.
* In a party, XP can be split by online member count.
* If payout shares are on, money follows the % splits.

***

### Party

* Leader picks the location, invites, kicks, and starts the job.
* `EnablePayoutShares = true` → set percentages in the lobby.
* `false` → everyone gets full payout.
* Member disconnect → job fails when `FailJobOnMemberDisconnect` is on.

***

### Escrow — what’s open vs encrypted?

#### OPEN (edit these)

* All `shared/*` (config, locations, shells, cores…)
* `locales/*`
* `client/core.lua`, `client/editable/**`
* `server/core.lua`, `server/editable/**`
* `sql/**`, `data/**`, `dui/**`

#### ENCRYPTED (don’t touch / can’t edit)

* `client/editable.lua` (bag/UV/blood gameplay config lives here but is encrypted)
* `client/main.lua`, `job.lua`, `bootstrap.lua`, `shells.lua`, …
* `server/main.lua`, `schedule.lua`, `missionBeforeImages.lua`, `version.lua`
* `ui/dist/**`

#### Editable files you’ll touch most

| File                                | What                                |
| ----------------------------------- | ----------------------------------- |
| `client/editable/vehicleKeys.lua`   | Give van keys                       |
| `client/editable/dispatch.lua`      | Police alert                        |
| `client/editable/lockpick.lua`      | Door minigame                       |
| `client/editable/vehiclePlate.lua`  | Plate                               |
| `client/editable/vehicleScene.lua`  | Vehicle scene (seat corpse, unlock) |
| `server/editable/weaponCleanup.lua` | Scene weapon models                 |
| `server/core.lua`                   | Give money / identifier             |

***

### `shared/cores.lua`

Tells the script how to find your framework:

* `es_extended` → ESX
* `qb-core` → QBCore
* `qbx_core` → Qbox

With `Config.Core = 'auto'`, the first matching started core wins. If you renamed your core resource, update this file or the config.

### Locales (`locales/*.lua`)

All player-facing text: UI, notifies, HUD.

1. Set `Config.Language = 'en'` (or `tr`, etc.)
2. Matching `locales/xx.lua` is used
3. Restart the resource

New language: copy an existing locale → add it to `fxmanifest.lua` `shared_scripts`.

***

### Stream resource

`izzy-illegalcleaner-stream` has **no Lua logic**. It contains:

* Melwia props (toolbag, UV, odor, bodybag, acidtub…)
* HQ exterior (`sp1_05_*`)
* Torture / melwia MLO + `interiorproxies.meta`

If it’s missing, props won’t load; the script may fall back to other models or look empty.

***

### qb-interior note

The script usually **CreateObject**s the shell itself. qb-interior’s job is to **stream** the models.

* Official [qb-interior](https://github.com/qbcore-framework/qb-interior) is enough
* Different resource name → `Config.ShellDefaults.resource = 'your-name'`
* Office / yacht / vehicle / pool may not depend on shells

***

### Security stuff (already in the script)

* No phase skipping (`jobPhase` only +1)
* Spot complete: distance + cooldown
* Corpse search state machine
* Complete distance checks (depot / scene / van)
* Risk bump cap
* Disconnect fail (config)
* Failed lockpick → optional dispatch


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://izzyshop-1.gitbook.io/izzyshop-docs/izzyshop-resources/izzy-illegalcleaner/overview.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
