# Installation

## Dependencies

{% tabs %}
{% tab title="QBCore" %}
QBCore Framework
{% endtab %}

{% tab title="ESX" %}
ESX Framework
{% endtab %}
{% endtabs %}

***

## How to install

Drag the script in your folder

Add the following item to `yourinventory/data/items.lua`\
QBCore users to `qbcore/shared/items.lua`\
\
Add the item image to your inventory/images

Run the `SQL` & restart your server.

{% hint style="info" %}
If you are using a different inventory then literally create the same items for your custom inventory.
{% endhint %}

{% tabs %}
{% tab title="QBCore" %}

```lua
-- Drug Phone
drugphone = { 
    name = 'drugphone', 
    label = 'Drug Phone', 
    weight = 0, 
    type = 'item', 
    image = 'drugphone.png', 
    unique = true, 
    useable = false, 
    shouldClose = false, 
    combinable = nil, 
    description = 'What a great Business Phone' 
},
```

{% endtab %}

{% tab title="ESX" %}

```lua
-- Drug Phone
['drugphone'] = {
  label = 'Drug Phone',
  weight = 0,
  client = {
    image = 'drugphone.png',
  },
},
```

{% endtab %}
{% endtabs %}

<figure><img src="https://dunb17ur4ymx4.cloudfront.net/packages/images/a476a844105f9e4f5560b397a3232f435d81bc05.gif" alt=""><figcaption></figcaption></figure>

***

* **StreetDealXP — XP per successful street deal**\
  Amount of XP granted each time a player completes (accepts) a street deal. Default: `2`.
* **DrugLevel — Level thresholds (cumulative XP)**\
  Total XP required to reach each level:\
  `1: 0, 2: 500, 3: 1,500, 4: 3,000, 5: 5,000, 6: 8,000, 7: 12,000, 8: 15,000, 9: 17,500, 10: 20,000`\
  \&#xNAN;*Note:* Values are cumulative; add more entries to extend the cap.

```lua
-- XP awarded for successful street deals (per accept)
Config.StreetDealXP = 2
-- Level/XP
Config.DrugLevel = {
    [1] = 0,
    [2] = 500,
    [3] = 1500,
    [4] = 3000,
    [5] = 5000,
    [6] = 8000,
    [7] = 12000,
    [8] = 15000,
    [9] = 17500,
    [10] = 20000,
}
```

***

* **DrugBuyers — Buyer categories**\
  Top-level list of drug buyer setups, grouped by category (e.g., Weed).
* **CategoryName — Display name**\
  The category label shown in UI/menus.
* **ItemList — Sellable items**\
  Array of items this category buys.
  * **Item**: Internal item name.
  * **Label**: UI display name.
  * **img**: Icon/texture key used in UI.
  * **minPrice / maxPrice**: Random sell price range per unit.
  * **allowStreetDeal**: Item can be sold on the street (true/false).
  * **allowDealerDeal**: Item can be sold to a dealer/NPC (true/false).
* **DrugContacts — Progression contacts**\
  NPC contacts unlocked by level; each entry:
  * **ContactName**: NPC name.
  * **Level**: Required player level to access.
  * **XP**: XP granted/used by your contact logic.
* **DrugBuyerLocations — Street buyer spawns**\
  List of spawn points as `{ x, y, z, heading }` for street deals.
* **Example (Weed)**\
  Includes street items like Joint and 2g strains (AK47, Amnesia, etc.) and a dealer-only **Weed Brick 100g** with higher price range.

```lua
[1] = {
    CategoryName = "Test Category",
    ItemList = {
        { Item= "item_name", Label= "Item Name", img= "img_name", minPrice= 50, maxPrice= 60, allowStreetDeal= false, allowDealerDeal= true },
    },
    DrugContacts = {
        { ContactName= "Phil Morb", Level= 1, XP= 100 },
        { ContactName= "Denis Klaf", Level= 2, XP= 100 },
    },
    DrugBuyerLocations = {
        -- x, y, z, heading
        { 339.48, -217.0, 54.22, 66.55 },
    },
},
```

<figure><img src="https://dunb17ur4ymx4.cloudfront.net/packages/images/edf0b75067e0bd746a71fc7b3840f8ea430594c5.gif" alt=""><figcaption></figcaption></figure>

***

* **DealTuning — Price & tension logic**\
  Master settings for street-deal success chance and tension effects.
* **HardCapMult — Price ceiling**\
  Max allowed offer = `item.maxPrice * 1.10`.
* **Tension — Bounds**\
  NPC tension scale: `0–100`.
* **DealDelays.MaxFailures — Auto-fail attempts**\
  Failed/hesitated tries at a spot before auto-fail: `3`.
* **UnderMin — Price ≤ minPrice**\
  Treated as success; tension drops `-2 … -1`.
* **WithinRange — minPrice < price ≤ maxPrice**\
  Chance = `BaseAtMin (85) − floor(pct * DropAcrossRange (20))`,\
  with `pct = (price−min)/(max−min)`, +`FirstDealBonus (5)`, clamped by `MinBaseChance (40)`.\
  On success: tension `-1 … 0`. On fail: tension `+2 … +6`; show `"The buyer hesitates..."`.
* **OverCap — maxPrice < price ≤ hardCap**\
  Chance = `AtMaxPrice (10) − floor(overPct * DropPerOverPct (50))`,\
  with `overPct = (price−max)/max(max,1)`, min `0`.\
  Success: tension `+10 … +15`. Fail: tension `+20 … +35`; show `"Too expensive..."`.
* **AboveHardCap — price > hardCap**\
  Always fail; tension `+30 … +45`; show `"Ridiculous price!"`.

```lua
-- Dealer deal price/tension tuning extracted from server logic
Config.DealTuning = {
    HardCapMult = 1.10,
    Tension = {
        Min = 0,
        Max = 100,
    },
    DealDelays = {
        MaxFailures = 3,
    },

    -- Case: price <= minPrice
    UnderMin = {
        TensionDelta = { Min = -2, Max = -1 },
    },

    -- Case: minPrice < price <= maxPrice
    WithinRange = {
        -- Chance formula: baseChance = BaseAtMin - floor(pct * DropAcrossRange)
        -- pct = (price - minPrice) / (maxPrice - minPrice)
        BaseAtMin       = 85,
        DropAcrossRange = 20,
        FirstDealBonus  = 5,
        MinBaseChance   = 40,

        -- On success: small tension decrease
        SuccessTensionDelta = { Min = -1, Max = 0 },
        -- On fail: tension increase and delay increments
        FailTensionDelta    = { Min = 2,  Max = 6 },
        FailMessage         = "The buyer hesitates... try a better price.",
    },

    -- Case: maxPrice < price <= hardCap
    OverCap = {
        -- Chance formula: chance = AtMaxPrice - floor(overPct * DropPerOverPct)
        -- overPct = (price - maxPrice) / max(maxPrice, 1)
        AtMaxPrice      = 10,
        DropPerOverPct  = 50,   -- 0.20 over => -10 => 0% chance
        MinChance       = 0,

        SuccessTensionDelta = { Min = 10, Max = 15 },
        FailTensionDelta    = { Min = 20, Max = 35 },
        FailMessage         = "Too expensive. Lower your price.",
    },

    -- Case: price > hardCap
    AboveHardCap = {
        TensionDelta = { Min = 30, Max = 45 },
        FailMessage  = "Ridiculous price! Don't try to rip me off.",
    },
}
```

<figure><img src="https://dunb17ur4ymx4.cloudfront.net/packages/images/368d19c71e26847fe098c06864777466265f174f.gif" alt=""><figcaption></figcaption></figure>


---

# 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://theftdev.gitbook.io/theftdev/theftdev-scripts/resources/drug-phone/installation.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.
