> For the complete documentation index, see [llms.txt](https://lunex-scripts.gitbook.io/lunex-scripts/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lunex-scripts.gitbook.io/lunex-scripts/lunex-scripts/hbalint_safezone.md).

# hbalint\_safezone

```
Quick Start:

ensure ox_lib
ensure oxmysql
ensure hbalint_notify
ensure hbalint_safezone
```

Default admin command:

```
/safezonecreator
```

Opens the **Admin Panel**. From there you can launch the Creator, edit zones, or delete them.

***

### Installation

#### 1. Copy the Resource

Place the resource in your server's `resources` folder:

```
resources/[hbalint]/[egyedi]/hbalint_safezone
```

#### 2. server.cfg

Dependencies must start **before** the safezone resource:

```cfg
ensure ox_lib
ensure oxmysql
ensure hbalint_notify
ensure hbalint_safezone
```

> If `hbalint_notify` is not installed, set `Config.Notify.provider` to `'ox_lib'` or `'custom'`.

#### 3. Configure

Open `config.lua` and set:

* `Config.Framework` — `'auto'`, `'esx'`, or `'qb'`
* `Config.AdminGroups` — admin permission (framework group based)
* `Config.Storage` — `'file'`, `'database'`, or `'config'`
* `Config.Locale` — `'hu'` or `'en'`

#### 4. Start

```cfg
ensure hbalint_safezone
```

Or perform a full server restart.

#### Storage Modes

**`file` (recommended)**

* Dynamic zones saved to: `data/safezones.json`
* Static zones from `Config.Safezones` are also loaded and merged
* Creator saves apply instantly without restart
* The resource folder must be **writable**

**`database`**

* Auto-creates table: `hbalint_safezones` (via oxmysql)
* Ideal for multi-server / larger setups
* Columns: `id`, `label`, `polygon`, `restrictions`, `show_blip`, `show_map_zone`

**`config`**

* Uses only `Config.Safezones`
* Runtime save/delete is **disabled** (read-only)

#### Permissions

Admin checks use **framework groups** (not ACE):

```lua
Config.AdminGroups = {
    owner = true,
    superadmin = true,
}
```

The player's group is returned by ESX/QBCore. If the creator does not start, verify the group is listed in `Config.AdminGroups`.

Supported formats:

* `{ groupName = true }` — table keys
* `{ 'owner', 'superadmin' }` — array (case-insensitive)

#### Static Zones in Config

If you do not want to use the creator, define zones directly:

```lua
Config.Safezones = {
    {
        id = 'legion',
        label = 'Legion Square',
        showBlip = true,
        showMapZone = true,
        polygon = {
            vec2(195.0, -930.0),
            vec2(230.0, -910.0),
            vec2(250.0, -970.0),
            vec2(200.0, -990.0),
        },
        restrictions = {
            disableWeapons = false,
        },
    },
}
```

***

### Configuration

All settings are in `config.lua`.

#### Framework & Locale

```lua
Config.Locale = 'en'        -- 'hu' | 'en'
Config.Framework = 'auto'   -- 'esx' | 'qb' | 'auto'
Config.CreatorCommand = 'safezonecreator'
```

#### Admin Groups

```lua
Config.AdminGroups = {
    owner = true,
}
```

#### Storage

```lua
Config.Storage = 'file'

Config.Database = {
    table = 'hbalint_safezones',
}
```

#### Creator Settings

```lua
Config.Creator = {
    minPoints = 3,
    maxPoints = 64,
    flyHeight = 25.0,
    pointRadius = 1.25,
    snapDistance = 2.5,
    lineWidth = 0.02,
    fillAlpha = 40,
    colors = { ... },
    controls = {
        place = 24,       -- Left click
        remove = 25,      -- Right click
        save = 191,       -- ENTER
        cancel = 194,     -- BACKSPACE
        deleteHover = 45, -- R
    },
}
```

#### Detection

```lua
Config.Detection = {
    outsideInterval = 500,  -- ms — outside zones
    insideInterval = 250,   -- ms — inside zones
    useHeight = false,      -- Include Z axis in detection
    minZ = -200.0,
    maxZ = 2000.0,
}
```

#### Restrictions (Global Defaults)

```lua
Config.Restrictions = {
    disablePvP = true,
    disableWeapons = true,
    disableShooting = true,
    disableMelee = true,
    disableVehicleCollision = true,
    disableNpcAttack = true,
    disableWanted = true,
    disableVehicleTheft = true,
}
```

Per-zone overrides use the `restrictions` field. See Restrictions & Detection.

#### Notify

```lua
Config.Notify = {
    enabled = true,
    provider = 'hbalint',  -- 'hbalint' | 'ox_lib' | 'custom'
    custom = {
        event = nil,
        resource = nil,
        export = nil,
        handler = nil,
    },
    title = 'Safezone',
    enter = 'You entered a safezone.',
    exit = 'You left the safezone.',
    -- ... additional messages
}
```

| Provider  | Behavior                                                                 |
| --------- | ------------------------------------------------------------------------ |
| `hbalint` | `hbalint_notify` exports (Success/Error/Info/Warning), fallback: ox\_lib |
| `ox_lib`  | `lib.notify()`                                                           |
| `custom`  | Custom handler, event, or export                                         |

#### HUD

```lua
Config.HUD = {
    enabled = true,
    text = 'SAFEZONE',
    showIcon = true,
    icon = 'shield',
    position = 'bottom-center', -- bottom-center | bottom-left | bottom-right
    offsetX = -220,
    offsetY = 48,
    colors = {
        background = '#090A12',
        border = '#23263A',
        text = '#F8FAFC',
        accent = '#7C5CFF',
        glow = 'rgba(124, 92, 255, 0.28)',
    },
    animation = {
        fadeMs = 280,
        pulse = true,
    },
}
```

#### Blip & Map Zone

```lua
Config.Blip = {
    sprite = 487,
    color = 2,
    scale = 0.85,
    shortRange = false,
}

Config.MapZone = {
    exactPolygon = true,
    showWorldZone = false,
    polygonOverlay = {
        fillAlpha = 100,
        borderAlpha = 220,
        -- ...
    },
    drawDistance = 350.0,
    blipColor = 2,
    mapAlpha = 55,
    fill = { r = 46, g = 204, b = 113, a = 55 },
    line = { r = 46, g = 204, b = 113, a = 180 },
}
```

Per-zone toggles (panel or on save):

* `showBlip` — icon on the map
* `showMapZone` — green area marker (minimap overlay + radius blip)

#### Localization

`Config.Locales` includes `hu` and `en`. The selected locale automatically overrides `Config.Notify` and `Config.CreatorHUD` strings.

```lua
Config.Locale = 'en'
```

***

### Admin Panel & Creator

#### Admin Panel

Command (from config, default):

```
/safezonecreator
```

Opens the **Safezone Manager** NUI panel. Only players with an allowed admin group can access it.

| Feature             | Description                                   |
| ------------------- | --------------------------------------------- |
| **Search**          | By name or ID                                 |
| **Create Safezone** | Launch creator mode                           |
| **Settings**        | Toggle blip and map zone                      |
| **Delete**          | Permanently delete a zone (with confirmation) |

The panel refreshes automatically after save or delete.

#### Creator Mode

Started via the **Create Safezone** button in the admin panel.

On enter:

1. Character is lifted (`flyHeight`)
2. Noclip is enabled
3. Creator HUD appears (control hints)

**Controls**

| Input            | Action                         |
| ---------------- | ------------------------------ |
| **Left click**   | Place / move point             |
| **Right click**  | Remove last point              |
| **R**            | Delete hovered point           |
| **ENTER**        | Save (name + blip/map options) |
| **BACKSPACE**    | Exit without saving            |
| **WASD**         | Noclip movement                |
| **SPACE / CTRL** | Up / down                      |
| **SHIFT**        | Faster noclip                  |
| **ALT**          | Slower noclip                  |

**Saving**

* Minimum **3**, maximum **64** points
* Name is required (ox\_lib input dialog)
* Optional: map blip, green map area
* Syncs to all clients immediately after save

#### Console Commands

| Command                | Description                        |
| ---------------------- | ---------------------------------- |
| `/safezonecreator`     | Open admin panel                   |
| `/safezonelist`        | List zones (chat notify / console) |
| `/safezonedelete [id]` | Delete zone by ID                  |
| `/safezonereload`      | Reload from storage                |

From server console (`source = 0`), delete/list/reload commands run without admin permission.

#### Security

* Creator start: server-side permission check
* Save: server validates points, name, coordinates
* Invalid coordinates (>10000) are rejected
* Enter/exit events: zone ID verification
* No runtime writes in `config` storage mode

***

### Restrictions & Detection

#### Detection

* **2D polygon** ray-casting algorithm (`vec2` coordinates)
* No markers for players — clean, optimized approach
* Outside zones: slower tick (`outsideInterval`, default 500 ms)
* Inside zones: faster check + restriction loop

**On Enter**

* Safezone HUD fade-in
* Notify (Success)
* State bag update: `safezone = true`, `safezoneId = zoneId`
* Server event: `hbalint_safezone:server:entered`

**On Exit**

* HUD fade-out
* Notify (Info)
* Restrictions reset (NPC, PvP, vehicle locks, etc.)
* State bag: `safezone = false`, `safezoneId = nil`

#### Restriction List

| Key                       | Effect                                   |
| ------------------------- | ---------------------------------------- |
| `disablePvP`              | Friendly fire disabled                   |
| `disableWeapons`          | Weapon use blocked                       |
| `disableShooting`         | Shooting blocked                         |
| `disableMelee`            | Melee blocked                            |
| `disableVehicleCollision` | Vehicle collision disabled (40m radius)  |
| `disableNpcAttack`        | NPCs do not attack, police ignore player |
| `disableWanted`           | Wanted level cleared                     |
| `disableVehicleTheft`     | Vehicle drag-out / theft blocked         |

#### Per-Zone Override

```lua
{
    id = 'hospital',
    label = 'Hospital',
    polygon = { vec2(...), vec2(...), vec2(...) },
    showBlip = true,
    showMapZone = true,
    restrictions = {
        disableWeapons = false,       -- weapons allowed
        disableVehicleCollision = true,
    },
}
```

Missing keys inherit from global `Config.Restrictions`.

#### State Bags

Readable from other scripts (strict mode compatible):

```lua
LocalPlayer.state.safezone      -- boolean
LocalPlayer.state.safezoneId    -- string | nil
```

Set by the server on enter/exit.

***

### Exports & API

#### Client Exports

```lua
-- Is the player inside a safezone?
local inside = exports['hbalint_safezone']:IsInSafezone()

-- Current zone data (nil if not inside)
local zone = exports['hbalint_safezone']:GetCurrentSafezone()
-- zone.id, zone.label, zone.polygon, zone.restrictions, ...

-- All loaded zones
local zones = exports['hbalint_safezone']:GetSafezones()

-- Is creator active?
local creating = exports['hbalint_safezone']:IsCreatorActive()

-- Is admin panel open?
local panelOpen = exports['hbalint_safezone']:IsPanelOpen()
```

#### Server Exports

```lua
-- All zones
local zones = exports['hbalint_safezone']:GetSafezones()

-- Is player in a safezone?
local inside = exports['hbalint_safezone']:IsPlayerInSafezone(source)

-- Player's current zone (nil if none)
local zone = exports['hbalint_safezone']:GetPlayerSafezone(source)

-- Reload storage + broadcast
exports['hbalint_safezone']:ReloadSafezones()
```

#### Mapzones Exports (Client)

Minimap polygon overlay system:

```lua
exports['hbalint_safezone']:addZone(data)
exports['hbalint_safezone']:removeZone(id)
exports['hbalint_safezone']:clearZones()
exports['hbalint_safezone']:getHoveredZone()
exports['hbalint_safezone']:getPlayerZone()
```

#### Events

**Client → Server**

| Event                                 | Description           |
| ------------------------------------- | --------------------- |
| `hbalint_safezone:server:entered`     | Player entered a zone |
| `hbalint_safezone:server:exited`      | Player left a zone    |
| `hbalint_safezone:server:save`        | Creator save          |
| `hbalint_safezone:server:delete`      | Delete zone           |
| `hbalint_safezone:server:update`      | Update blip/mapZone   |
| `hbalint_safezone:server:requestSync` | Request zone sync     |

**Server → Client**

| Event                                  | Description          |
| -------------------------------------- | -------------------- |
| `hbalint_safezone:client:sync`         | Sync zones to client |
| `hbalint_safezone:client:openPanel`    | Open admin panel     |
| `hbalint_safezone:client:startCreator` | Start creator        |
| `hbalint_safezone:client:notify`       | Send notify          |

#### Integration Example

```lua
-- Client
CreateThread(function()
    while true do
        Wait(1000)
        if exports['hbalint_safezone']:IsInSafezone() then
            -- Block weapon equip, etc.
        end
    end
end)

-- Server
RegisterNetEvent('myresource:attack', function()
    if exports['hbalint_safezone']:IsPlayerInSafezone(source) then
        return
    end
    -- attack logic
end)
```

***

### Troubleshooting

#### Creator / Panel Won't Start

* Check `Config.AdminGroups` — is the player's framework group listed?
* Is the framework running (`es_extended` / `qb-core`)?
* With `Config.Framework = 'auto'`, wait a few seconds after startup
* Enable debug: `Config.Debug = true` — admin check logs appear in console

#### Save Not Working

* `Config.Storage = 'config'` intentionally disables saving
* In `file` mode, the resource folder must be writable (`data/safezones.json`)
* In `database` mode, verify `oxmysql` connection
* Minimum 3 points required to save

#### HUD Not Visible

* `Config.HUD.enabled = true`
* NUI files loaded (`fxmanifest.lua` → `files`)
* Check F8 console for NUI errors

#### Notify Not Showing

* `Config.Notify.enabled = true`
* Provider settings:
  * `hbalint` → `ensure hbalint_notify` before safezone
  * `ox_lib` → ox\_lib notify must work
* Fallback: if `hbalint_notify` is missing, it falls back to ox\_lib automatically

#### Zone Not Detected

* Are polygon points valid (minimum 3, valid vec2)?
* `Config.Detection.useHeight` — if true, Z coordinate is also checked
* `/safezonereload` — reload from storage

#### Blip / Map Zone Not Visible

* Zone must have `showBlip = true` / `showMapZone = true`
* Can also be toggled in the admin panel after save
* `Config.MapZone.drawDistance` — world-drawn zone distance

#### Debug Mode

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

Console output includes:

* Number of loaded zones
* Admin permission check results
* Save events

***

### Optimization

* Outside zones: `Config.Detection.outsideInterval` (default 500 ms)
* Inside zones: restriction tick (control blocking only)
* Creator mode: draw loop runs only while active
* No unnecessary markers or blips for players (optional per zone)
* Single full sync event after save

```
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://lunex-scripts.gitbook.io/lunex-scripts/lunex-scripts/hbalint_safezone.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
