# Configuration

## ⚙️ Config

The `Config.lua` file is the **central control panel** of the script. Every value here changes how the lab behaves in-game, from prices and XP all the way to plant positions and admin commands.

> ⚠️ **Warning:** After editing `Config.lua`, you must **restart the resource** for the changes to apply.

***

### 🧩 General Settings

```lua
Config.DropPlayer = false
Config.MainModel  = '3z_weedlap'
Config.LabZOffset = -22.5
Config.DoorWidth  = 1.6
Config.MaxLevel   = 24
Config.UpgradeCooldown   = 3
Config.UpgradeConfirmAt  = 50000
```

| Key                | Type    | Description                                                                              |
| ------------------ | ------- | ---------------------------------------------------------------------------------------- |
| `DropPlayer`       | boolean | Kicks players caught cheating / exploiting the lab.                                      |
| `MainModel`        | string  | **Resource name** — must match the folder name on your server (`3z_weedlap` by default). |
| `LabZOffset`       | number  | Vertical offset for the lab interior. Lower if the lab spawns above the ground.          |
| `DoorWidth`        | number  | Distance (meters) at which lab doors open/close automatically.                           |
| `MaxLevel`         | number  | Maximum upgrade level a lab can reach.                                                   |
| `UpgradeCooldown`  | number  | Seconds between consecutive upgrade purchases (anti-spam).                               |
| `UpgradeConfirmAt` | number  | Cash threshold above which a **confirmation popup** appears before purchase.             |

***

### 🌉 Bridge Settings

The Bridge layer is what makes the script compatible with **multiple frameworks and inventories** without changing the code.

```lua
Config.Bridge = {
    Framework = 'auto',
    Inventory = 'auto',
    Notify    = 'auto',
    Target    = 'auto',
    DrawText  = 'auto',
}
```

#### Framework Options

* `auto` — auto-detect (`qbx_core` → `qb-core` fallback)
* `qb` — force QBCore
* `qbx` — force QBox

#### Inventory Options

* `ox_inventory`
* `qb-inventory`

#### Notify Options

* `ox_lib`
* `qb`

#### Target Options

* `ox_target`
* `qb-target`
* `interact`

#### DrawText Options

* `qb-ui`
* `ox_lib`

> ✅ **Tip:** Leave everything on `auto` if you're not sure — the script will detect installed resources automatically at startup.

```lua
Config.Base = {
    core     = 'qb-core',
    interact = 'interact',
}
```

Legacy fallback only — the Bridge handles the real logic. Don't touch unless you renamed `qb-core`.

```lua
Config.InventoryQB = {
    ResourceName = "qb-inventory",
    Events = {
        ItemBox         = "inventory:client:ItemBox",
        OpenInventory   = "inventory:server:OpenInventory",
        SetCurrentStash = "inventory:client:SetCurrentStash",
    }
}
```

Events used **only by QB-style inventories**. `ox_inventory` ignores this section.

***

### 📦 Items Reference

```lua
Config.Items = {
    lab_tablet       = "lab_tablet",
    weed_nutrition   = "weed_nutrition",
    weed_pot         = "weed_pot",
    water_bottle_big = "water_bottle_big",
    weed_baggy_empty = "weed_baggy_empty",
    weedscissors     = "weedscissors",
    hack_lab         = "hack_lab",
}
```

| Key                | Purpose                                              |
| ------------------ | ---------------------------------------------------- |
| `lab_tablet`       | Opens the labs management UI.                        |
| `weed_nutrition`   | Plant fertilizer.                                    |
| `weed_pot`         | Empty pot used to plant a seed.                      |
| `water_bottle_big` | Water bottle that refills the water tank.            |
| `weed_baggy_empty` | Empty baggy used in cleaning recipes.                |
| `weedscissors`     | Required to harvest grown plants.                    |
| `hack_lab`         | Required to hack a foreign lab keypad during a raid. |

> 💡 **Note:** Change the **value** (right side) to match your inventory item name — never the key on the left.

***

### 📡 Discord Logs

```lua
Config.DiscordLogs = {
    enabled    = true,
    serverName = "X8 Project",
    webhook    = "",
    webhooks = {
        lab    = "",
        snitch = "",
        attack = "",
    },
}
```

| Key               | Description                                                          |
| ----------------- | -------------------------------------------------------------------- |
| `enabled`         | Master switch. Set to `false` to disable all logs.                   |
| `serverName`      | Shown as the bot name in Discord.                                    |
| `webhook`         | Default webhook URL — used as fallback when a category URL is empty. |
| `webhooks.lab`    | Lab events (purchase, upgrade, harvest…).                            |
| `webhooks.snitch` | Snitch / informant activity.                                         |
| `webhooks.attack` | Raid attack logs.                                                    |

***

### 📍 Lab Offsets

`Config.offset` contains **local coordinates** (relative to the lab anchor — not world coords).

#### Weed Pots

```lua
Config.offset.weedPot = {
    [0] = { ... },  -- Base sheet (16 pots)
    [1] = { ... },  -- Sheet 2 (upgrade required)
    [2] = { ... },  -- Sheet 3
    [3] = { ... },  -- Sheet 4
    [4] = { ... },  -- Sheet 5
    [5] = { ... },  -- Sheet 6
}
```

* The first index is the **sheet (tier)** — `[0]` is unlocked by default, the rest require upgrades.
* The second index is the **slot number** inside that sheet (1 → 16).

#### Cameras

```lua
Config.offset.Cameras = {
    [1] = { label = "CAM #1", coords = vector3(...), rot = vector3(...) },
    ...
}
```

15 CCTV positions used by the camera setup command.

#### Chairs (Weed area)

```lua
Config.offset.Chairs = {
    [1] = {
        coords  = vector3(...),  -- chair base
        sit     = vector3(...),  -- sit position
        anim    = vector3(...),  -- where the table animation plays
        heading = 274.61,
        leave   = vector3(...),  -- where the player teleports when leaving
        upgrade = nil,           -- upgrade ID required (nil = unlocked)
    },
    ...
}
```

#### Chairs (Laundry area) & Laundry Dryers

Same structure — chair 1 / dryer 1 are unlocked by default, the rest are tied to upgrade IDs (`dryer_2`, `laundry_chair_2`, etc.).

***

### 🏚️ Pre-defined Gang Labs

```lua
Config.Weedlap = {
    ["vagos"] = {
        label      = "GangLab #1",
        management = vector3(2767.18, 4010.26, 54.24),
        doorid     = {8, 9, 10},
    },
}
```

| Key           | Description                                                        |
| ------------- | ------------------------------------------------------------------ |
| key (`vagos`) | The gang name (must match the gang in `qb-core/shared/gangs.lua`). |
| `label`       | Display name in UI / map blip.                                     |
| `management`  | World coordinates where the gang leader manages the lab purchase.  |
| `doorid`      | List of ox\_doorlock IDs used by the lab.                          |

***

### 🌱 Plants

```lua
Config.Plant = {
    ['weedbask']    = { ... },
    ['bluedream']   = { ... },
    ['yellowdream'] = { ... },
}
```

Example:

```lua
['bluedream'] = {
    label      = 'Blue Dream',
    seed       = 'seed_bluedream',
    bud        = 'bud_bluedream',
    baggie     = 'bluedream_bag',
    budMin     = 5,
    budMax     = 8,
    BudsForBag = 5,
    PlacingProgressBarDuration = 5,
    RequirePot    = true,
    PotItem       = 'weed_pot',
    RemovePot     = 1,
    RequireShovel = false,
    RemoveShovel  = 0,
    Props = {
        [1] = 'an_weed_blue_01_small_01a',
        [2] = 'an_weed_blue_med_01b',
        [3] = 'an_weed_blue_lrg_01a',
    },
}
```

| Key                              | Description                                                     |
| -------------------------------- | --------------------------------------------------------------- |
| `label`                          | Display name in UI.                                             |
| `seed` / `bud` / `baggie`        | Item names for the seed, harvested bud, and pre-filled baggy.   |
| `budMin` / `budMax`              | Random range of buds per harvest.                               |
| `BudsForBag`                     | How many buds make 1 bag.                                       |
| `PlacingProgressBarDuration`     | Seconds the planting animation lasts.                           |
| `RequirePot` / `PotItem`         | Plant requires an empty pot when planting.                      |
| `RemovePot`                      | How many pots are consumed per plant.                           |
| `RequireShovel` / `RemoveShovel` | Same logic for shovels.                                         |
| `Props[1..3]`                    | Prop models for plant stages (seedling → medium → fully grown). |

***

### 📈 Plant Growth

```lua
Config.PlantGrowth = {
    WaterPerUse  = 20,
    FeedPerUse   = 30,
    TickInterval = 60,

    BaseGrowth = {2, 4},
    FoodBonus  = {1, 2},
    WaterDrain = {8, 12},
    FoodDrain  = {6, 10},

    DecayEnabled  = true,
    DecayBoth     = 6,
    DecayNoWater  = 3,
    DecayNoFood   = 1,
    DeadTicks     = 3,
    ...
}
```

| Key                                        | Description                                          |
| ------------------------------------------ | ---------------------------------------------------- |
| `WaterPerUse`                              | How much water 1 use adds to the plant.              |
| `FeedPerUse`                               | How much fertilizer 1 use adds.                      |
| `TickInterval`                             | Seconds between each growth tick.                    |
| `BaseGrowth {min,max}`                     | Random growth gained per tick when stats are normal. |
| `FoodBonus`                                | Bonus growth when food level is high.                |
| `WaterDrain` / `FoodDrain`                 | Random drain per tick.                               |
| `DecayEnabled`                             | Allow HP loss when starving.                         |
| `DecayBoth`                                | HP loss when both water AND food are empty.          |
| `DecayNoWater`                             | HP loss when only water is empty.                    |
| `DecayNoFood`                              | HP loss when only food is empty.                     |
| `DeadTicks`                                | Ticks of starvation before the plant dies.           |
| `HighFoodThreshold`                        | Minimum food level to count as "high".               |
| `PeakThreshold`                            | Threshold for "peak" state — both stats high.        |
| `PeakBonus`                                | Extra growth at peak state.                          |
| `MaxMomentum` / `MomentumStep`             | Snowball growth buff system.                         |
| `SlowWaterThreshold` / `SlowGrowthPenalty` | Growth slowdown when water is low.                   |
| `OverfeedThreshold` / `OverfeedPenalty`    | Growth penalty when overfed.                         |
| `StartWater` / `StartFood`                 | Starting values for a freshly planted seed.          |
| `MinDistance`                              | Minimum distance between two plants.                 |
| `Lifetime` / `StarveTime`                  | Plant lifetime and starvation duration (seconds).    |

***

### 💧 Water Tank

```lua
Config.WaterTank = {
    model        = 'prop_watercrate_01',
    refillItem   = 'water_bottle_big',
    baseCapacity = 100,
    refillAmount = 25,
}
```

| Key            | Description                                 |
| -------------- | ------------------------------------------- |
| `model`        | Prop spawned in the lab.                    |
| `refillItem`   | Item used to refill the tank.               |
| `baseCapacity` | Default tank size (boostable via upgrades). |
| `refillAmount` | How much water 1 bottle adds.               |

***

### 🧪 Cleaning Recipes

```lua
Config.Clean = {
    [1] = {
        label       = "Basic Pack",
        description = "10x bud_weedbask + 1x weed_baggy_empty",
        RequiredItems = {
            { item = "bud_weedbask",     count = 10, remove = true },
            { item = "weed_baggy_empty", count = 1,  remove = true },
        },
        AddItems = {
            { item = "weedbag_1", count = 1 },
        },
        Log = "...",
        Roll = {
            label = "Basic Joint",
            RequiredItems = { ... },
            AddItems = { { item = "joint", count = 3 } },
            Log = "...",
        },
    },
    [2] = { ... },  -- Standard
    [3] = { ... },  -- Premium
}
```

Each tier defines:

* **Pack recipe** — convert buds + empty baggy into a packed weed bag.
* **Roll recipe** (inside `Roll`) — convert buds + pack into joints.

| Field                  | Description                           |
| ---------------------- | ------------------------------------- |
| `label`                | Display name.                         |
| `description`          | Recipe description.                   |
| `RequiredItems`        | Items required to use the recipe.     |
| `RequiredItems.remove` | If `true`, the item is consumed.      |
| `AddItems`             | Items added when the recipe succeeds. |
| `Log`                  | Discord log message.                  |

***

### 🛠️ Upgrades

```lua
Config.Upgrades = {
    entire  = { ... },  -- whole-lab upgrades (tanks, safe, unlock laundry)
    weed    = { ... },  -- weed-area upgrades (chairs, planting sheets)
    laundry = { ... },  -- laundry-area upgrades (dryers, speed, yield)
    drug    = {},
}
```

Each entry:

```lua
{ id = "tank_upgrade_1", name = "Water Tank I", level = 0,
  desc = "Tank capacity: 150L", cashPrice = 8000, coinPrice = 700, capacity = 150 }
```

| Field                | Description                                   |
| -------------------- | --------------------------------------------- |
| `id`                 | Unique upgrade ID (used internally in code).  |
| `name`               | Display name.                                 |
| `level`              | Minimum lab level required to buy.            |
| `desc`               | Upgrade description.                          |
| `cashPrice`          | Cost in money.                                |
| `coinPrice`          | Cost in **lab coins** (earned from XP gains). |
| `capacity` / `slots` | Extra fields used by specific upgrades.       |

***

### ⚔️ Raids

```lua
Config.Raids = {
    RaidPrice           = 5000,
    CooldownAfterAttack = 5,
    ImmunityAfterLose   = 45,
    ImmunityAfterRaided = 40,
    RaidRadius          = 450.0,
    LootDuration        = 10,
    MinAttackers = 0,
    MinDefenders = 0,
    PhaseKeypad    = 15,
    PhaseShutdown  = 1,
    PhaseLaptop    = 10,
    PhaseCode      = 10,
    PhaseCountdown = 5,
    HackRounds    = 5,
    HackArrows    = 10,
    HackTimeLimit = 40,
    LaptopDifficulty = 4,
    LaptopTime       = 20,
    KeypadFailMode  = 'time',
    KeypadRetryDelay = 8,
    KeypadMaxRetries = 2,
    LaptopFailMode  = 'time',
    LaptopRetryDelay = 10,
    LaptopMaxRetries = 2,
}
```

#### General Raid

| Key                             | Description                                       |
| ------------------------------- | ------------------------------------------------- |
| `RaidPrice`                     | Cost (in $) to start a raid against another lab.  |
| `CooldownAfterAttack`           | Minutes between raids (per attacker).             |
| `ImmunityAfterLose`             | Minutes a lab can't be raided after losing.       |
| `ImmunityAfterRaided`           | Minutes a lab can't be raided after being raided. |
| `RaidRadius`                    | Meters around the lab where the raid is active.   |
| `LootDuration`                  | Time (minutes) the loot remains lootable.         |
| `MinAttackers` / `MinDefenders` | Minimum members required to start/defend.         |

#### Phases

| Key              | Description                       |
| ---------------- | --------------------------------- |
| `PhaseKeypad`    | Keypad hack phase duration (min). |
| `PhaseShutdown`  | Shutdown phase.                   |
| `PhaseLaptop`    | Laptop hack phase.                |
| `PhaseCode`      | Code-entry phase.                 |
| `PhaseCountdown` | Final countdown.                  |

#### Minigames

| Key                               | Description              |
| --------------------------------- | ------------------------ |
| `HackRounds`                      | Keypad minigame rounds.  |
| `HackArrows`                      | Keypad arrows per round. |
| `HackTimeLimit`                   | Seconds allowed.         |
| `LaptopDifficulty` / `LaptopTime` | Laptop minigame.         |

#### Fail Modes

```lua
KeypadFailMode = 'time'   -- or 'lose', 'retry'
```

* `lose` — instant loss on fail.
* `retry` — allow up to `MaxRetries` with `RetryDelay` seconds between tries.
* `time` — no penalty; player keeps trying until phase ends.

***

### 🎯 XP & Levels

```lua
Config.XP = {
    Harvest  = {10, 30},
    Water    = {2,  8},
    Feed     = {2,  8},
    Plant    = {5,  15},
    Clean    = {5,  15},
    Roll     = {8,  20},
    RaidWin  = {50, 150},
    RaidLose = {10, 30},
}
```

Each entry is a `{min, max}` random range.

```lua
Config.LevelXP = {
    [0]  = 0,     [1]  = 3375,  ... [24] = 81000,
}
```

Index = level number, value = total XP required.

***

### 🏛️ Mafia Panel

```lua
Config.Mafia = {
    menuCoords = vector3(1396.16, 1132.48, 113.85),
    mafia      = "mafia",
    guard      = 2,
}
```

| Key          | Description                          |
| ------------ | ------------------------------------ |
| `menuCoords` | World coords where the panel spawns. |
| `mafia`      | Gang name with access.               |
| `guard`      | Minimum gang grade required.         |

***

### 👑 Gang Management

```lua
Config.GangManagement = {
    bossGrade    = 3,
    useSQL       = true,
    playersTable = 'players',
    cidColumn    = 'citizenid',
    gangColumn   = 'gang',
}
```

| Key            | Description                                                                  |
| -------------- | ---------------------------------------------------------------------------- |
| `bossGrade`    | Minimum grade to manage the gang (kick / promote / delete lab).              |
| `useSQL`       | `true` = read/write gang data directly from SQL (works for offline players). |
| `playersTable` | SQL table where players are stored.                                          |
| `cidColumn`    | Column name for citizenid.                                                   |
| `gangColumn`   | Column name for gang JSON.                                                   |

***

### 💼 Lab Purchase

```lua
Config.LabPurchase = {
    requireBoss      = true,
    bossGrade        = 3,
    blockIfGangOwns  = true,
    currency         = "bank",
    itemName         = "goldcoin",
    ped = {
        model    = "a_m_m_hillbilly_01",
        offset   = vector3(-2.7422, 20.1311, 12.9),
        heading  = 26.66,
        scenario = "WORLD_HUMAN_SMOKING",
    },
    blipSprite = 140,
    blipColor  = 2,
    blipScale  = 0.9,
    blipLabel  = "Lab For Sale",
    markerColor   = {r = 255, g = 180, b = 0, a = 120},
    interactLabel = "Purchase Lab",
    interactIcon  = "fa-solid fa-cash-register",
}
```

| Key                 | Description                                        |
| ------------------- | -------------------------------------------------- |
| `requireBoss`       | Only the gang boss can buy.                        |
| `bossGrade`         | Minimum grade considered "boss".                   |
| `blockIfGangOwns`   | Block buying if the gang already owns a lab.       |
| `currency`          | `"cash"` or `"bank"`.                              |
| `itemName`          | Alternative item that can be used as payment.      |
| `ped`               | NPC details (model / offset / heading / scenario). |
| `blip*` / `marker*` | Blip and marker styling.                           |

***

### 🔐 Safe

```lua
Config.Safe = {
    model     = 'p_v_43_safe_s',
    maxWeight = 100000,
    label     = 'Lab Safe',
}
```

***

### 💵 Laundry

```lua
Config.Laundry = {
    Models = {
        empty   = 'bkr_prop_prtmachine_dryer',
        loaded  = 'bkr_prop_prtmachine_dryer_op',
        running = 'bkr_prop_prtmachine_dryer_spin',
    },
    InputItem     = 'dirty_money',
    PayoutPerItem = 1500,
    TimePerItem   = 4000,
    MaxPerWash    = 100,
    Label         = 'Money Dryer',
    Anim = { dict = '...', clip = '...' },
    Chair = {
        Amount   = 10,
        Duration = 8000,
        Anim = { dict = '...', clip = '...' },
        Label = 'Count Dirty Money',
    },
}
```

| Key             | Description                                     |
| --------------- | ----------------------------------------------- |
| `Models`        | Prop models for empty / loaded / running dryer. |
| `InputItem`     | Item required to wash.                          |
| `PayoutPerItem` | Cash earned per item washed.                    |
| `TimePerItem`   | Milliseconds per item.                          |
| `MaxPerWash`    | Maximum items per wash cycle.                   |
| `Anim`          | Dryer animation.                                |
| `Chair`         | Chair that converts cut bills into dirty money. |

***

### 🖨️ Print Machine

```lua
Config.Print = {
    Label       = 'Printing Machine',
    MaxPerBatch = 50,
    Time        = 6000,
    InputPaper  = { item = 'blank_paper', perSheet = 1 },
    InputInk    = { item = 'printer_ink', perSheet = 1 },
    Output      = { item = 'dollar_sheet' },
    Debug       = false,
}
```

Converts `blank_paper` + `printer_ink` → `dollar_sheet`.

***

### ✂️ Paper Cutter

```lua
Config.Cutter = {
    Label  = 'Paper Cutter',
    Time   = 5000,
    Input  = { item = 'dollar_sheet', amount = 1 },
    Output = { item = 'cut_dollar',   amount = 45 },
    Debug  = false,
}
```

Converts 1 `dollar_sheet` → 45 `cut_dollar` (60 with the `cutter_yield` upgrade).

***

### 🚪 Door

```lua
Config.Door = {
    OpenAngle    = 90.0,
    SoundEnabled = true,
}
```

***

### 🗺️ Blip Settings

```lua
Config.BlipSettings = {
    blipSprite    = 140,
    blipColor     = 1,
    blipColorMine = 2,
    blipScale     = 0.8,
}
```

| Key             | Description                      |
| --------------- | -------------------------------- |
| `blipColor`     | Color for **other** gangs' labs. |
| `blipColorMine` | Color for **your own** gang lab. |

***

### ⌨️ Admin Commands

```lua
Config.Commands = {
    labsetup = {
        enabled     = true,
        permissions = {"god", "admin"},
        jobs        = {},
        gangs       = {"mafia"},
        identifiers = {},
        denyMessage = "You are not allowed to use labsetup.",
    },
    editlab     = { ... },
    cctv_setup  = { ... },
    chair_setup = { ... },
    pot_setup   = { ... },
    dellabsale  = { ... },
}
```

| Field         | Description                                  |
| ------------- | -------------------------------------------- |
| `enabled`     | Master switch for the command.               |
| `permissions` | Ace permission groups allowed.               |
| `jobs`        | Allow specific jobs.                         |
| `gangs`       | Allow specific gangs.                        |
| `identifiers` | Extra license / steam / discord IDs allowed. |
| `denyMessage` | Message shown when access is denied.         |

#### Available Commands

| Command       | Purpose                    |
| ------------- | -------------------------- |
| `labsetup`    | Initial lab setup tool.    |
| `editlab`     | Edit an existing lab.      |
| `cctv_setup`  | Place / move CCTV cameras. |
| `chair_setup` | Place / move chairs.       |
| `pot_setup`   | Place / move plant pots.   |
| `dellabsale`  | Remove a lab sale.         |

***

### 🌉 Bridge Auto-Detect (Internal)

The bottom of `Config.lua` initializes the **Bridge core** — auto-detects which framework, inventory, notify, target, and drawtext system you have installed.

> 🛑 **Danger:** Do NOT edit the bridge core section unless you know exactly what you're doing. Use `Config.Bridge` at the top instead.

Boot log example:

```
[X8-WeedlaP] [SERVER] Framework=qb Inventory=ox_inventory Notify=ox_lib Target=ox_target DrawText=ox_lib
```

If you see weird detection results, force the systems manually in `Config.Bridge`.


---

# 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://x8project.gitbook.io/x8project/projects/weed-lab/configuration.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.
