# nova\_target

NOVA Framework raycast targeting system (third-eye). Provides a context menu for interacting with entities, models, zones, and global elements.

## Features

* **Global Options** — Add options to all peds, vehicles, players, or objects
* **Model Targeting** — Add options to specific model hashes
* **Entity Targeting** — Add options to specific entity network IDs
* **Zone Targeting** — Box, sphere, and polygon zones with options
* **ox\_target Compatibility** — Drop-in replacement for ox\_target
* **qb-target Compatibility** — Drop-in replacement for qb-target

## Configuration

Edit `config.lua`:

```lua
Config.Key = 'LMENU'               -- Key to activate targeting (Left Alt)
Config.MaxDistance = 7.0            -- Maximum raycast distance
Config.DrawDistance = 10.0          -- Distance to draw target indicator
Config.EnableCompat = true          -- Enable ox_target/qb-target compatibility
Config.Debug = false                -- Show debug zones
```

### Configuration Options

| Option         | Type    | Default   | Description              |
| -------------- | ------- | --------- | ------------------------ |
| `Key`          | string  | `'LMENU'` | Activation key name      |
| `MaxDistance`  | number  | `7.0`     | Raycast distance         |
| `DrawDistance` | number  | `10.0`    | Indicator draw distance  |
| `EnableCompat` | boolean | `true`    | Enable compat layer      |
| `Debug`        | boolean | `false`   | Debug zone visualization |

## Exports

### Global Options

```lua
-- Add option to all peds
exports['nova_target']:addGlobalPed({
    {
        name = 'talk_to_ped',
        icon = 'fas fa-comment',
        label = 'Talk',
        onSelect = function(data)
            -- Your logic
        end,
        canInteract = function(entity, distance, data)
            return true
        end,
    }
})

-- Remove global ped option
exports['nova_target']:removeGlobalPed('talk_to_ped')
```

### Global Vehicle / Player / Object

```lua
exports['nova_target']:addGlobalVehicle(options)
exports['nova_target']:removeGlobalVehicle(name)

exports['nova_target']:addGlobalPlayer(options)
exports['nova_target']:removeGlobalPlayer(name)

exports['nova_target']:addGlobalObject(options)
exports['nova_target']:removeGlobalObject(name)
```

### Model Targeting

```lua
exports['nova_target']:addModel('s_m_m_doctor_01', {
    {
        name = 'doctor_menu',
        icon = 'fas fa-briefcase-medical',
        label = 'Open Medical Menu',
        onSelect = function(data)
            -- Open menu
        end,
    }
})

exports['nova_target']:removeModel('s_m_m_doctor_01')
```

### Entity Targeting

```lua
-- By network ID
exports['nova_target']:addEntity(netId, options)
exports['nova_target']:removeEntity(netId)

-- Local entity (not networked)
exports['nova_target']:addLocalEntity(entityHandle, options)
exports['nova_target']:removeLocalEntity(entityHandle)
```

### Zone Targeting

```lua
-- Box zone
exports['nova_target']:addBoxZone({
    name = 'my_box',
    coords = vector3(x, y, z),
    size = vector3(2.0, 2.0, 2.0),
    rotation = 0.0,
    debug = false,
    options = {
        {
            name = 'interact',
            icon = 'fas fa-hand',
            label = 'Interact',
            onSelect = function() end,
        }
    }
})

-- Sphere zone
exports['nova_target']:addSphereZone({
    name = 'my_sphere',
    coords = vector3(x, y, z),
    radius = 2.0,
    options = { ... }
})

-- Polygon zone
exports['nova_target']:addPolyZone({
    name = 'my_poly',
    points = { vector2(x1,y1), vector2(x2,y2), ... },
    minZ = 28.0,
    maxZ = 32.0,
    options = { ... }
})

-- Remove zone
exports['nova_target']:removeZone('my_box')

-- Check if zone exists
local exists = exports['nova_target']:zoneExists('my_box')
```

### Utility

```lua
-- Disable/enable targeting
exports['nova_target']:disableTargeting(true)    -- Disable
exports['nova_target']:disableTargeting(false)   -- Enable

-- Check if targeting is active
local active = exports['nova_target']:isActive()
```

## Option Format

Each option in an options array:

| Property      | Type     | Required | Description                           |
| ------------- | -------- | -------- | ------------------------------------- |
| `name`        | string   | Yes      | Unique identifier                     |
| `icon`        | string   | No       | FontAwesome icon class                |
| `label`       | string   | Yes      | Display text                          |
| `onSelect`    | function | Yes      | Callback when selected                |
| `canInteract` | function | No       | Condition check (return true/false)   |
| `distance`    | number   | No       | Override max distance for this option |
| `groups`      | table    | No       | Required job/gang groups              |

## Compatibility

When `Config.EnableCompat` is true, the resource provides compatibility with:

* **ox\_target** — All ox\_target exports work as-is
* **qb-target** — All qb-target exports work as-is

This means scripts written for ox\_target or qb-target will work with `nova_target` without modification.

### Compatibility Exports (PascalCase)

```lua
exports['nova_target']:AddBoxZone(name, coords, length, width, options, targetOptions)
exports['nova_target']:AddCircleZone(name, coords, radius, options, targetOptions)
exports['nova_target']:AddTargetEntity(entity, options)
exports['nova_target']:AddTargetModel(model, options)
exports['nova_target']:AddGlobalPed(options)
-- ... and more
```

## Dependencies

* None — This is a standalone resource

## Notes

* Hold the activation key (Left Alt by default) to enter targeting mode
* A crosshair/eye icon appears when targeting is active
* Options appear in a context menu when hovering over a valid target
* The `canInteract` function is called every frame while targeting — keep it lightweight
* Zone debug mode (`Config.Debug = true`) draws zone outlines for development
