> For the complete documentation index, see [llms.txt](https://gnstudio.gitbook.io/doc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gnstudio.gitbook.io/doc/los-santos/vespucci-police-department/elevator-script.md).

# VSPD Elevator script

🚪 Vespucci Elevators System

### Overview

The **Vespucci Elevator System** (`cfx_gn_vespucci_elevator_script`) allows players to **use elevators seamlessly without teleportation**.\
The system automatically configures itself on startup and integrates perfectly with interaction frameworks.

***

### ⚙️ Setup

1. **Start the resource:**

   ```lua
   ensure cfx_gn_vespucci_elevator_script
   ```
2. That’s it — everything is configured automatically.\
   If you prefer teleportation-based elevators, simply **do not start this resource**.

***

### 🧭 Teleportation vs. Physical Elevators

<table><thead><tr><th width="171.8070068359375">Mode</th><th width="273.9649658203125">Description</th><th>How to Enable</th></tr></thead><tbody><tr><td><strong>Non-Teleportation (default)</strong></td><td>Elevators move physically without teleporting the player.</td><td>Start the <code>cfx_gn_vespucci_elevator_script</code> resource.</td></tr><tr><td><strong>Teleportation</strong></td><td>The classic mode where players are instantly teleported between floors.</td><td>Do <strong>not</strong> start the resource; manage entitysets manually.</td></tr></tbody></table>

{% hint style="info" %}
Please note you can disable the whole interaction by setting true to Elevator.Config.DisableInteraction in the config file of the elevator script. You will need to enable the static elevator.
{% endhint %}

#### How to enable static elevator?

In \`cfx\_gn\_vespucci\_pd\`, you can enable the entities missing in the \`Config.lua\` by setting true to Config.StaticElevators.

***

### 🧩 Interaction Integration Example

You can register your own interactions with elevators by using the built-in exports from `gn_elevator`.

```lua
function LoadVespucciInteractions()
    if GetResourceState("cfx_gn_vespucci_elevator_script") ~= "started" then return end

    local gnElevator = exports.cfx_gn_vespucci_elevator_script
    local elevators = gnElevator:GetElevatorConfigs()

    for elevatorId, elevator in pairs(elevators) do
        -- Register each floor panel
        for id, floorCfg in pairs(elevator.floors) do
            RegisterInteractionSpot("elev_panel_" .. elevatorId .. "_" .. id, floorCfg.panel + vec3(0, 0, 1.25), {
                point = { text = "call", distance = 5.0 },
                canLoad = function()
                    return gnElevator:GetElevatorCurrentFloor(elevatorId) ~= id and not gnElevator:IsInAnyElevator()
                end,
                onInteract = function()
                    gnElevator:CallElevator()
                end
            })
        end

        -- Register lift interaction
        RegisterInteractionModel(elevator.model, {
            point = { text = "use", distance = 5.0 },
            offset = elevator.insidePanelOffset,
            skipVisionCheck = true,
            skipRoomCheck = true,
            canLoad = function()
                return gnElevator:IsInAnyElevator()
            end,
            onInteract = function()
                gnElevator:OpenElevatorKeypad()
            end
        })
    end
end
```

***

### 🔐 Access Control

You can restrict or allow access to be call from specific floors per player.

| Function                                                  | Description                                                           |
| --------------------------------------------------------- | --------------------------------------------------------------------- |
| `CanPlayerAccessFloor(elevatorId, floorIndex)`            | Returns whether a player has permission to go to the specified floor. |
| `SetPlayerAccessFloor(elevatorId, floorIndex, canAccess)` | Grants or removes access to a floor for the current player.           |

***

### 📦 Exported Functions

Below is the complete list of available exports for integration with other scripts.

| Export                                       | Arguments           | Returns             | Description                                                  |
| -------------------------------------------- | ------------------- | ------------------- | ------------------------------------------------------------ |
| **`OpenElevatorKeypad()`**                   | none                | –                   | Opens the keypad UI inside an elevator.                      |
| **`CallElevator()`**                         | none                | –                   | Calls the elevator to the current floor.                     |
| **`GetElevatorCurrentFloor(elevatorId)`**    | `string elevatorId` | `number floorIndex` | Gets the current floor of a specific elevator.               |
| **`IsInElevator(elevatorId)`**               | `string elevatorId` | `boolean`           | Returns whether the player is currently in a given elevator. |
| **`IsInAnyElevator()`**                      | none                | `boolean`           | Returns `true` if the player is in *any* elevator.           |
| **`SetElevatorInteractionEnabled(enabled)`** | `boolean enabled`   | –                   | Enables or disables all elevator interaction.                |

***

### 🧠 Notes

* The system dynamically links to the main `cfx_gn_vespucci_elevator_script` resource.
* Each elevator’s floor and model information is automatically discovered.
* Interactions can be safely added or removed at runtime.
* Access control allows complex logic (e.g. jobs, keycards, staff, etc.).
