> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cc-scripts.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

> Drop the resource in, register the ox_inventory items, stream the jammer assets, ensure after cc_heistcontracts.

## Requirements

* A FiveM server already running [cc\_heistcontracts](/cc_heistcontracts/installation).
* [ox\_lib](https://github.com/overextended/ox_lib) and [oxmysql](https://github.com/overextended/oxmysql).
* A working `cc_lib` resource.
* An inventory system (defaults assume **ox\_inventory**).
* Streaming enabled on the server — the resource ships custom jammer assets.

## Steps

<Steps>
  <Step title="Place the resource">
    Copy `cc_pacificheist` into a resources directory the server loads. The repo ships under `resources/[cc]/cc_pacificheist/`. The `stream/` folder must travel with it — the custom jammer props live there.
  </Step>

  <Step title="Add the inventory items">
    <Tabs>
      <Tab title="ox_inventory">
        Add the following items to `ox_inventory/data/items.lua`

        ```lua theme={null}
        laptop_elite = { label = 'BlackBook Mk-III', weight = 3200, stack = false },
        signal_jammer = { label = 'Signal Jammer', weight = 400 },
        thermite = { label = 'Thermite Charge', weight = 800 },
        electric_drill = { label = 'Cordless Drill', weight = 1800, stack = false },
        ```

        Drop the matching item images into `ox_inventory/web/images/` (filenames must match the name of the item).

        <Note>
          The `weapon_digiscanner` and `weapon_assaultrifle` requirements are standard ox\_inventory weapons — no extra config needed if you're on the stock weapons list.
        </Note>

        <Note>
          In the shipped Qbox `items.lua` the `thermite` entry exists but is **commented out** at line \~830. Uncomment it before launching this heist.
        </Note>
      </Tab>

      <Tab title="qb-inventory">
        Add the following items to `qb-core/shared/items.lua`

        ```lua theme={null}
        laptop_elite = { name = 'laptop_elite', label = 'BlackBook Mk-III', weight = 3200, unique = true, type = 'item', image = 'laptop_elite.png', useable = false },
        signal_jammer = { name = 'signal_jammer', label = 'Signal Jammer', weight = 400, unique = false, type = 'item', image = 'signal_jammer.png', useable = false },
        thermite = { name = 'thermite', label = 'Thermite Charge', weight = 800, unique = false, type = 'item', image = 'thermite.png', useable = false },
        electric_drill = { name = 'electric_drill', label = 'Cordless Drill', weight = 1800, unique = true, type = 'item', image = 'electric_drill.png', useable = false },
        ```

        Drop the matching item images into `qb-inventory/html/images/` (filenames must match the image field).

        <Note>
          The `weapon_digiscanner` and `weapon_assaultrifle` requirements are standard qb-inventory weapons — no extra config needed if you're on the stock weapons list.
        </Note>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configure gabz map-data">
    Changes need to be made in `cfx-gabz-mapdata/gabz_entityset_mods1.lua`

    Replace the `gabz_sm_pb_milo` entry with this:

    ```lua theme={null}
      {
          ipl = 'gabz_sm_pb_milo',
          coords = { x = 260.01200000, y = 220.73300000, z = 108.64600000 },
          entitySets = {
              { name = 'room01_entrance', enable = true },
              { name = 'room02_mainhall', enable = true },
              { name = 'room03_sideentrance', enable = true },
              { name = 'room04_roofstairs', enable = true },
              { name = 'room05_office01', enable = true },
              { name = 'room06_office02', enable = true },
              { name = 'room07_office03', enable = true },
              { name = 'room08_office04', enable = true },
              { name = 'room09_office05', enable = true },
              { name = 'room10_office06', enable = true },
              { name = 'room11_office07', enable = true },
              { name = 'room12_office08', enable = true },
              { name = 'room13_mainoffice', enable = true },
              { name = 'room14_vaultstairs', enable = true },
              { name = 'room15_vaultbasement', enable = true },
              { name = 'room16_vault', enable = true },
              { name = 'room16_vault_trolleys', enable = false }, -- cash trolleys (cc_pacificheist spawns its own)
          }
      },
    ```

    The `room16_vault_trolleys` entry must be disabled — `cc_pacificheist` spawns its own trolley props during the run and the gabz set would duplicate them.
  </Step>

  <Step title="Ensure after cc_heistcontracts">
    Order in `server.cfg`:

    ```
    ensure oxmysql
    ensure ox_lib
    ensure cc_lib
    ensure cc_heistcontracts
    ensure cc_pacificheist
    ```

    `cc_pacificheist`'s `fxmanifest.lua` already declares `cc_heistcontracts` as a dependency.
  </Step>

  <Step title="Verify the jammer assets are streaming">
    The custom jammer props require the `data_file 'DLC_ITYP_REQUEST' 'stream/cc_jammer.ytyp'` line in `fxmanifest.lua` (already present). On first boot, watch the server console for:

    ```
    Streaming pacificheist resource 'cc_jammer.ytyp'
    ```

    No error = good. If clients see invisible jammers, the `.ytyp` isn't being read — check that `this_is_a_map 'yes'` is still in `fxmanifest.lua`.
  </Step>

  <Step title="(Optional) Tune the jammer difficulty">
    `shared/config.lua`:

    ```lua theme={null}
    cfg.jammer = {
        drainSeconds = 90,    -- 100% → 0% takes this many seconds with no maintain
        bumpAmount   = 40,    -- +% on a successful maintain
        beepWarn     = 40,    -- start slow beep when signal ≤ this %
        beepCritical = 20,    -- switch to fast beep when signal ≤ this %
    }
    cfg.maintain_timer = 5 * 60   -- maintain cooldown per jammer (seconds)
    ```

    Raise `drainSeconds` for a more forgiving fight; drop `bumpAmount` to make maintain runs more critical.
  </Step>

  <Step title="Register the bank doors">
    <Tabs>
      <Tab title="ox_doorlock">
        Set `cfg.auto_insert_doors = true` in `shared/config.lua` and the resource will insert its doors into the `ox_doorlock` table on first start (skipping any names already present). Leave it `false` if you manage doors manually.
      </Tab>

      <Tab title="qb-doorlock">
        `cfg.auto_insert_doors` only targets `ox_doorlock`. On `qb-doorlock`, paste these entries into `qb-doorlock/config/locations.lua` (inside `Config.DoorList`) and restart `qb-doorlock`. The manager's office is a `double` door:

        ```lua theme={null}
        Config.DoorList['pacific-managers_office'] = {
            doors = {
                { objHash = 1109357065, objYaw = 70,  objCoords = vec3(273.18389892578, 216.86282348632, 110.28051757812) },
                { objHash = 1109357065, objYaw = 250, objCoords = vec3(272.4721069336, 214.90727233886, 110.28051757812) },
            },
            textCoords = vec3(272.82800292968, 215.8850402832, 110.28051757812),
            locked = true, pickable = false, distance = 2, doorType = 'double'
        }
        Config.DoorList['pacific-cellar_right'] = {
            objHash = 409280169,
            objCoords  = vec3(272.6421508789, 219.8987121582, 97.317977905274),
            textCoords = vec3(272.6421508789, 219.8987121582, 97.317977905274),
            objYaw = 340, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-cellar_left'] = {
            objHash = 409280169,
            objCoords  = vec3(270.10321044922, 212.92292785644, 97.317977905274),
            textCoords = vec3(270.10321044922, 212.92292785644, 97.317977905274),
            objYaw = 340, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-cellar_left_hall'] = {
            objHash = 409280169,
            objCoords  = vec3(251.6498413086, 216.19061279296, 97.317977905274),
            textCoords = vec3(251.6498413086, 216.19061279296, 97.317977905274),
            objYaw = 250, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-cellar_right_hall'] = {
            objHash = 409280169,
            objCoords  = vec3(256.41244506836, 229.2759399414, 97.317977905274),
            textCoords = vec3(256.41244506836, 229.2759399414, 97.317977905274),
            objYaw = 70, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-cellar_left_loot'] = {
            objHash = 409280169,
            objCoords  = vec3(244.55801391602, 216.89727783204, 97.317977905274),
            textCoords = vec3(244.55801391602, 216.89727783204, 97.317977905274),
            objYaw = 340, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-cellar_right_loot'] = {
            objHash = 409280169,
            objCoords  = vec3(250.56420898438, 233.39938354492, 97.317977905274),
            textCoords = vec3(250.56420898438, 233.39938354492, 97.317977905274),
            objYaw = 340, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-vault_inside_left'] = {
            objHash = 643152522,
            objCoords  = vec3(229.89053344726, 227.34201049804, 97.323974609375),
            textCoords = vec3(229.89053344726, 227.34201049804, 97.323974609375),
            objYaw = 340, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-vault_inside_right'] = {
            objHash = 643152522,
            objCoords  = vec3(225.64628601074, 228.88677978516, 97.323974609375),
            textCoords = vec3(225.64628601074, 228.88677978516, 97.323974609375),
            objYaw = 160, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-reception4'] = {
            objHash = -2121568016,
            objCoords  = vec3(251.51986694336, 215.71315002442, 106.3702468872),
            textCoords = vec3(251.51986694336, 215.71315002442, 106.3702468872),
            objYaw = 250, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-reception1'] = {
            objHash = -2121568016,
            objCoords  = vec3(256.60681152344, 229.68962097168, 106.3702468872),
            textCoords = vec3(256.60681152344, 229.68962097168, 106.3702468872),
            objYaw = 70, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-reception2'] = {
            objHash = -2121568016,
            objCoords  = vec3(270.23065185546, 221.2673034668, 106.3702468872),
            textCoords = vec3(270.23065185546, 221.2673034668, 106.3702468872),
            objYaw = 70, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-reception3'] = {
            objHash = -2121568016,
            objCoords  = vec3(267.3699645996, 213.40798950196, 106.3702468872),
            textCoords = vec3(267.3699645996, 213.40798950196, 106.3702468872),
            objYaw = 250, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-staircase_back'] = {
            objHash = 267980221,
            objCoords  = vec3(277.59533691406, 223.5415802002, 106.3804321289),
            textCoords = vec3(277.59533691406, 223.5415802002, 106.3804321289),
            objYaw = 160, locked = true, pickable = false, distance = 2
        }
        Config.DoorList['pacific-entrance_back'] = {
            objHash = 267980221,
            objCoords  = vec3(272.7904663086, 206.48045349122, 106.38217163086),
            textCoords = vec3(272.7904663086, 206.48045349122, 106.38217163086),
            objYaw = 340, locked = true, pickable = false, distance = 2
        }
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="(Optional) Disable the bank manager">
    By default a manager ped (`IG_Avery`) spawns at his PC armed with a pistol and shoots the crew. Set `cfg.enable_manager = false` in `shared/config.lua` to skip him.
  </Step>

  <Step title="Verify in-game">
    1. Grant a profile **level 5** (`/heist:grantxp <playerId> 1500` reaches level 5 on the default curve).
    2. Open the dashboard via the `heist_tablet`. **Pacific Bank Heist** drips into the marketplace at weight 0.2 — it's rare. Lower `config.rotation.dripIntervalMs` or temporarily bump the contract `weight` to 1.0 in `shared/contract.lua` to test.
    3. Buy it for 2,500 VICE, gather the items, drive to downtown.

    <Tip>
      With `cfg.debug = true` plus the manager disabled, you can solo the contract to verify task progression without fighting the cops dispatched on `vault_panel`.
    </Tip>
  </Step>
</Steps>

## Customising loot

`shared/rewards.lua` is the global loot table. When `cfg.use_global_loot_table = true` (default), totals are split across all lockers and all trolleys.

```lua theme={null}
return {
    lockers = {
        { type = 'item', item = 'black_money', amount = { min = 1000, max = 2000 } },
        { type = 'money',                       amount = { min = 1000, max = 2000 } },
    },
    trolleys = {
        { type = 'item', item = 'black_money', amount = { min = 1000, max = 2000 } },
        { type = 'money',                       amount = { min = 1000, max = 2000 } },
    },
}
```

The Pacific heist has **three loot rooms** (`left`, `right`, `inside`), each containing lockers and trolleys. The global table applies the rolled totals across every locker across every room, and similarly for trolleys. For per-room control, set `use_global_loot_table = false` and define `rewards` tables on each unit in `shared/location.lua`.
