# CodeRanch - cBoxDelivery

A professional box delivery job system for RedM with route-based missions, leveling, cooperative gameplay, leaderboards, job history.

***

## Requirements

| Dependency     | Required                                          |
| -------------- | ------------------------------------------------- |
| **cBase**      | Yes                                               |
| **oxmysql**    | Yes                                               |
| **ox\_target** | Optional (only if interaction type is `"target"`) |

***

## Installation

1. Place the `cBoxDelivery` folder into your server's resources directory.
2. Add `ensure cBoxDelivery` to your `server.cfg` (make sure `cBase` and `oxmysql` start before it).
3. The database table is created automatically on first start — no manual SQL required.
4. Edit `config.lua` to customize settings to your server's needs.
5. Restart your server.

***

## Configuration

All configuration is done in `config.lua`. No code changes are needed.

### Debug Mode

```lua
Config.Debug = true
```

Enables detailed console logging. Set to `false` for production.

***

### Level System

```lua
Config.LevelSystem = {
    BaseXP     = 80,
    Multiplier = 20,
    Exponent   = 1.6,
}
```

| Field        | Description                               | Default |
| ------------ | ----------------------------------------- | ------- |
| `BaseXP`     | Base XP amount applied to all levels      | `80`    |
| `Multiplier` | Scales XP cost per level                  | `20`    |
| `Exponent`   | Growth curve steepness (higher = steeper) | `1.6`   |

**Formula:** `XP_needed = floor(BaseXP + (level ^ Exponent) * Multiplier)`

| Level   | XP Needed |
| ------- | --------- |
| 1 → 2   | 100       |
| 5 → 6   | 247       |
| 10 → 11 | 876       |
| 25 → 26 | 3,610     |
| 50 → 51 | 10,957    |
| 80 → 81 | 23,463    |

***

### Rewards

```lua
Config.Rewards = {
    moneyPerBox = 2,
    xpPerBox    = 5,
}
```

| Field         | Description                         | Default |
| ------------- | ----------------------------------- | ------- |
| `moneyPerBox` | Base money earned per delivered box | `$2`    |
| `xpPerBox`    | Base XP earned per delivered box    | `5`     |

These values are multiplied by the route multiplier (and coop multiplier for XP).

***

### Interaction

```lua
Config.Interaction = {
    type     = "target",
    pedModel = "re_wagonthreat_males_01",
    pedCoord = vector4(2915.59, 1320.34, 43.52, 249.21),
}
```

| Field      | Description                               | Options                              |
| ---------- | ----------------------------------------- | ------------------------------------ |
| `type`     | How the player interacts with the job NPC | `"target"`, `"drawtext"`, `"prompt"` |
| `pedModel` | NPC model hash                            | Any valid ped model                  |
| `pedCoord` | NPC spawn location and heading            | `vector4(x, y, z, heading)`          |

* **target** — Uses ox\_target (requires ox\_target resource)
* **drawtext** — Shows a text prompt on screen when nearby
* **prompt** — Uses native RDR2 prompt system

***

### Badge NPC

```lua
Config.TakeBadge = {
    pedModel = "re_domesticdispute_females_01",
    pedCoord = vector4(2903.64, 1356.29, 51.75, 284.61),
}
```

The badge NPC is where players pick up their delivery uniform before starting a job. This NPC spawns when the player begins the badge step and disappears after 25 seconds.

***

### Blips

```lua
Config.Blips = {
    enabled = true,
    name    = "Box Delivery Job",
    sprite  = -1656531561,
}
```

| Field     | Description       | Default              |
| --------- | ----------------- | -------------------- |
| `enabled` | Show blip on map  | `true`               |
| `name`    | Blip label on map | `"Box Delivery Job"` |
| `sprite`  | Blip icon hash    | `-1656531561`        |

***

### Coop Settings

```lua
Config.Coop = {
    maxMembers   = 4,
    xpMultiplier = 1.25,
    leaveCommand = "coopleave",
}
```

| Field          | Description                                 | Default            |
| -------------- | ------------------------------------------- | ------------------ |
| `maxMembers`   | Maximum players per group (including owner) | `4`                |
| `xpMultiplier` | XP bonus multiplier for coop missions       | `1.25` (25% bonus) |
| `leaveCommand` | Chat command to leave a coop group          | `"coopleave"`      |

***

### Job Outfit

```lua
Config.JobOutfit = {
    male = {
        Shirt = 1133296213,
        Pant  = 28202123,
        Boots = 1485106129,
    },
    female = {
        Shirt = 1133296213,
        Pant  = 28202123,
        Boots = 1485106129,
    },
}
```

Players automatically change into this outfit when taking the badge and revert to their original outfit when the job ends. You can set different outfits for male and female characters using clothing component hashes.

***

### Wagons

```lua
Config.BoxModel = "p_strongbox_muddy_01x"
```

| Wagon  | Model         | Capacity | Deposit |
| ------ | ------------- | -------- | ------- |
| Small  | `wagon05x`    | 10 boxes | $40     |
| Medium | `supplywagon` | 20 boxes | $80     |
| Big    | `wagon04x`    | 40 boxes | $160    |

The deposit is paid upfront when selecting a wagon and **refunded in full** upon successful delivery completion. If the player quits the job, the deposit is lost.

Each wagon also has configurable box positioning:

```lua
boxOffsets = {
    startX = -0.38, startY = 0.4, startZ = 0.35,
    spacingX = 0.38, spacingY = 0.42, spacingZ = 0.1,
    cols = 5, rows = 3,
}
```

**Wagon Spawn Location:**

```lua
Config.WagonSpawnCoord = vector4(2917.71, 1312.12, 44.06, 158.98)
```

**Wagon Preview Camera:**

```lua
Config.WagonSelection = {
    camera = vector4(2966.36, 1301.93, 43.89, 71.0),
    wagons = vector4(2958.72, 1305.26, 44.49, 160.69),
}
```

***

### Routes

There are 4 delivery routes, each with a level requirement and reward multiplier:

| Route       | Level Required | Multiplier | Drop Points |
| ----------- | -------------- | ---------- | ----------- |
| Annesburg   | 1              | 1.0x       | 11          |
| Blackwater  | 40             | 1.5x       | 19          |
| Valentine   | 60             | 1.75x      | 22          |
| Saint Denis | 80             | 2.0x       | 33          |

Each route has its own set of delivery drop points scattered across the town. When a job starts, the drop points are **shuffled randomly** using the Fisher-Yates algorithm, so delivery order is different every time.

If the wagon capacity exceeds the number of available drop points, the route list cycles and reshuffles to fill the remaining boxes.

Route configuration example:

```lua
Config.Routes = {
    ["annesburg"] = {
        label = "Annesburg",
        route_id = 1,
        maincoord = { x = 2548.23, y = 1357.57 },
        required_level = 1,
        multiplier = 1.0,
        dropPoints = {
            vector4(2966.97, 1419.21, 45.05, 36.83),
            -- ... more coordinates
        }
    },
}
```

***

### Commands

| Command         | Description                                     |
| --------------- | ----------------------------------------------- |
| `/quitdelivery` | Quit the current delivery job (deposit is lost) |
| `/showRoute`    | Show the current delivery route on the map      |
| `/coopleave`    | Leave the current coop group                    |

***

## How It Works

### Job Flow

{% stepper %}
{% step %}

### Take Badge

Walk to the badge NPC and pick up your delivery uniform
{% endstep %}

{% step %}

### Select Wagon

Choose from 3 wagon sizes using the preview camera
{% endstep %}

{% step %}

### Select Route

Pick a delivery route (locked by level requirement)
{% endstep %}

{% step %}

### Start Delivery

Wagon spawns with boxes loaded, GPS guides you to drop points
{% endstep %}

{% step %}

### Deliver All Boxes

Pick up boxes from wagon, carry them to markers, and drop them off
{% endstep %}

{% step %}

### Return Wagon

Drive the wagon back to the spawn point
{% endstep %}

{% step %}

### Receive Rewards

Get your deposit back + money and XP earned
{% endstep %}
{% endstepper %}

***

### Delivery Process

{% stepper %}
{% step %}
The wagon spawns at the configured spawn location with boxes loaded on it.
{% endstep %}

{% step %}
A GPS waypoint marks the next delivery point.
{% endstep %}

{% step %}
The player approaches the wagon and picks up a box (animated pickup).
{% endstep %}

{% step %}
The player carries the box to the marked drop point (carry animation plays while walking).
{% endstep %}

{% step %}
At the drop point, the player puts down the box (animated putdown).
{% endstep %}

{% step %}
The delivery tracker UI updates with progress (e.g., "5/20 boxes delivered").
{% endstep %}

{% step %}
The next GPS waypoint appears automatically.
{% endstep %}

{% step %}
After all boxes are delivered, the player returns the wagon to the spawn point.
{% endstep %}

{% step %}
Rewards are distributed and the job outfit is removed.
{% endstep %}
{% endstepper %}

***

### Level & XP System

* Players start at **Level 1** with 0 XP.
* XP required per level increases exponentially using the formula:

  ```
  XP = floor(BaseXP + (level ^ Exponent) * Multiplier)
  ```
* There is **no level cap** — progression is unlimited.
* XP is earned per box delivered, modified by route and coop multipliers.
* Level-up notifications trigger instantly when a new level is reached.
* The UI shows current level, XP progress bar, and XP needed for next level.

***

### Cooperative System

The coop system allows up to 4 players to work together on delivery missions.

Creating a Group:

{% stepper %}
{% step %}
The owner opens the Coop tab in the UI.
{% endstep %}

{% step %}
Search for players by character name.
{% endstep %}

{% step %}
Send invites — invited players see a prompt to accept or reject.
{% endstep %}

{% step %}
Once all members are ready, the owner starts the job.
{% endstep %}
{% endstepper %}

Coop Job Mechanics:

* Wagon size is automatically selected based on the **average level** of all members.
* Route is automatically selected based on the best available route for the group's average level.
* Total box count scales with player count: `wagon capacity × number of members`.
* All members deliver to the same shared pool of drop points.
* Each member's deliveries sync to all teammates in real time.

Coop Rewards:

* Each member receives full money rewards (not split).
* All members receive a **1.25x XP bonus**.
* Deposit is paid by the owner and refunded only to the owner.

Coop Rules:

* Only the owner can start the job, kick members, or cancel.
* Members can leave at any time using `/coopleave`.
* If the owner disconnects, the group is automatically disbanded.

Auto Wagon Selection (Coop):

| Average Level | Wagon             |
| ------------- | ----------------- |
| Below 40      | Small (10 boxes)  |
| 40–59         | Medium (20 boxes) |
| 60+           | Big (40 boxes)    |

***

### Leaderboard

* Displays the **Top 8** players ranked by level (then XP as tiebreaker).
* If the current player is not in the top 8, their personal rank is shown separately.
* Each entry shows: rank number, player name, and level.
* Updates dynamically from the database.

***

### Job History

* Every completed (and cancelled) job is recorded in the player's history.
* History entries include:
  * Route name and wagon type
  * Completion time (minutes:seconds)
  * Money earned and XP earned
  * Current level and XP to next level
  * Start timestamp
  * Whether the job was cancelled
  * Whether it was a coop mission
* Displayed in the History tab with most recent jobs first.

***

### Wiki

The in-game wiki provides information about:

* **Wagons** — Description, capacity, and image for each wagon tier
* **Routes** — Description, level requirement, and map location for each route

Wiki data is configured in `wiki.lua`.

***

## UI Pages

The script features a modern **Vue 3** web interface with 5 pages:

| Page            | Description                                                                  |
| --------------- | ---------------------------------------------------------------------------- |
| **Home**        | Job setup — badge step, wagon selection, route selection, start button       |
| **Coop**        | Team management — search players, send invites, view members, start coop job |
| **Leaderboard** | Top 8 rankings by level and XP with personal rank                            |
| **History**     | Complete job history with stats for every delivery                           |
| **Wiki**        | Information about wagons and routes                                          |

An additional **Delivery Tracker** overlay appears during active missions showing real-time box delivery progress.

***

## Database

The script automatically creates its database table on first start. No manual SQL setup is required.

### Table: `cboxdelivery`

| Column           | Type         | Default | Description                    |
| ---------------- | ------------ | ------- | ------------------------------ |
| `identifier`     | VARCHAR(60)  | —       | Player identifier              |
| `charIdentifier` | INT          | —       | Character ID                   |
| `level`          | INT          | 1       | Current level                  |
| `xp`             | INT          | 0       | Total accumulated XP           |
| `user_fullname`  | VARCHAR(120) | NULL    | Character full name            |
| `history`        | JSON         | NULL    | Array of completed job records |

***

## Supported Languages

The script includes full localization for 6 languages:

| Language | Code |
| -------- | ---- |
| English  | `en` |
| Turkish  | `tr` |
| Arabic   | `ar` |
| French   | `fr` |
| Italian  | `it` |
| Spanish  | `es` |

All UI text, notifications, prompts, and messages are translated. The language is configured through `cBase`.

***

## Reward Calculations

### Formula

```
Money per box = floor(moneyPerBox × route_multiplier)
XP per box    = floor(xpPerBox × route_multiplier × coop_multiplier)
Total money   = money_per_box × total_boxes
Total XP      = xp_per_box × total_boxes
```

* `coop_multiplier` is `1.0` for solo jobs and `1.25` for coop jobs.

### Solo Job Examples

| Route              | Wagon  | Boxes | Money/Box | Total Money | XP/Box | Total XP |
| ------------------ | ------ | ----- | --------- | ----------- | ------ | -------- |
| Annesburg (1.0x)   | Small  | 10    | $2        | $20         | 5      | 50       |
| Annesburg (1.0x)   | Big    | 40    | $2        | $80         | 5      | 200      |
| Blackwater (1.5x)  | Medium | 20    | $3        | $60         | 7      | 140      |
| Valentine (1.75x)  | Big    | 40    | $3        | $120        | 8      | 320      |
| Saint Denis (2.0x) | Big    | 40    | $4        | $160        | 10     | 400      |

### Coop Job Examples (1.25x XP Bonus)

| Route              | Players | Wagon  | Total Boxes | Money/Person | XP/Person |
| ------------------ | ------- | ------ | ----------- | ------------ | --------- |
| Blackwater (1.5x)  | 2       | Medium | 40          | $120         | 350       |
| Valentine (1.75x)  | 3       | Big    | 120         | $360         | 1,200     |
| Saint Denis (2.0x) | 4       | Big    | 160         | $640         | 2,000     |

> **Note:** In coop jobs, each player receives the full money amount — rewards are not split. The deposit is paid and refunded to the owner only.
