# Property Integration

### Property Integration

This is the **most important section** for server owners who want crafting in apartments/houses.

#### How Property Integration Works

The script uses the `lvs_bridge` events to sync workbenches placed inside properties:

1. **Player enters property**: `lvs_bridge:server:enterProperty` is triggered
2. **Script loads** property-specific workbenches from database
3. **Player exits property**: `lvs_bridge:server:exitProperty` is triggered
4. **Script unloads** property workbenches from client

#### Required Bridge Events

Your property system (apartments/houses) **must trigger** these events:

**Server-Side Events**

**When a player enters a property:**

```lua
TriggerEvent('lvs_bridge:server:enterProperty', playerId, propertyType, propertyId, extra)
```

* `playerId` (number): Player server ID (optional, defaults to source)
* `propertyType` (string): `'house'`, `'apartment'`, etc.
* `propertyId` (string): Unique property identifier
* `extra` (any): Extra data (optional)

**When a player exits a property:**

```lua
TriggerEvent('lvs_bridge:server:exitProperty', playerId)
```

* `playerId` (number): Player server ID (optional, defaults to source)

**Client-Side Events**

The bridge also provides client events (usually auto-handled):

* `lvs_bridge:client:enterProperty`
* `lvs_bridge:client:exitProperty`

#### Integration Steps

1. **Locate your property script** (apartments, housing, etc.)
2. **Find where players enter/exit properties** - typically:
   * After teleporting to interior
   * Before loading interior
   * On leaving/despawning interior
3. **Add the event triggers**:

```lua
-- When player enters (server-side or client-side)
-- If from client, use:
TriggerServerEvent('lvs_bridge:server:enterProperty', nil, 'apartment', 'A1')

-- When player exits
TriggerServerEvent('lvs_bridge:server:exitProperty')
```

4. **Test the integration**:
   * Enter a property
   * Place a workbench (if you have the item)
   * Exit and re-enter - workbench should persist
   * Another player entering same property should see the workbench

***

#### Example Integration with qbx\_properties

If using qbx\_properties, locate the enter/exit events:

```lua
-- In properties/server/property.lua or similar
function EnterProperty(playerSource, id, isSpawn)
  ...
  -- Before load decorations...
	TriggerEvent('lvs_bridge:server:enterProperty', playerSource, 'apart', id) -- here
	TriggerClientEvent('qbx_properties:client:loadDecorations', playerSource, decorations)
	...
end
```

```lua
-- In qbx_properties/server/property.lua or similar
local function exitProperty(playerSource, isLogout)
  ...
  -- Before unload...
	TriggerEvent('lvs_bridge:server:exitProperty', playerSource) -- here
	TriggerClientEvent('qbx_properties:client:unloadProperty', playerSource)
	...
end
```

***

#### Example Integration with qb-apartments

If using qb-apartments, locate the enter/exit events:

```lua
-- In qb-apartments/client/main.lua or similar
RegisterNetEvent('qb-apartments:client:enterApartment', function(apartmentId)
    -- After teleport...
    TriggerServerEvent('lvs_bridge:server:enterProperty', nil, 'apartment', apartmentId)
end)

RegisterNetEvent('qb-apartments:client:leaveApartment', function()
    -- Before teleport out...
    TriggerServerEvent('lvs_bridge:server:exitProperty')
end)
```

***

### Placement Validation

`server/editable.lua` `_canPlaceWorkbench` Function, checks whether a player can currently place a crafting workbench at their current location.

#### Description

This function is executed when the server receives a request to place a crafting workbench. Its main purpose is to validate if the player meets the necessary requirements, specifically whether they are inside a property that allows placing workbenches.

The system retrieves the property data where the player is located using `_getPlayerPropertyData()`. If the player is not in a property, they cannot place the workbench.

Allows implementing custom logic to restrict certain types of workbenches based on property type. For example, preventing large crafting tables from being placed in small apartments.

#### Parameters

| Parameter       | Type     | Description                                                                                                                                                            |
| --------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `playerId`      | `number` | Server ID (source) of the player attempting to place the workbench                                                                                                     |
| `workbenchName` | `string` | Name of the workbench item to be placed (e.g., `'lvs_crafting_table_large'`)                                                                                           |
| `extra`         | `table?` | Additional information sent from the `lvs_bridge:server:enterProperty` trigger. May contain extra property data or additional context. Nil if no information was sent. |

#### Returns

| Type      | Description                                                             |
| --------- | ----------------------------------------------------------------------- |
| `boolean` | Returns `true` if the player can place the workbench, `false` otherwise |

#### Return Values

* **`true`**: Player is inside a property and meets all requirements to place the workbench
* **`false`**: Either:
  * Player is not inside any property, OR
  * Custom restrictions prevent placing this specific workbench type in the current property

#### Example Usage

#### Default Behavior

By default, the function allows placing any workbench if the player is inside a property:

```lua
if playerProperty then
    return true
end
return false
```

#### Custom Restriction Example

Prevent placing large crafting tables in apartments:

```lua
if playerProperty then
    if playerProperty.type == 'apartment' and workbenchName == 'lvs_crafting_table_large' then
        return false
    end
    return true
end
return false
```

#### Advanced Custom Logic

You can implement more complex restrictions:

```lua
function _canPlaceWorkbench(playerId, workbenchName, extra)
    local playerProperty = _getPlayerPropertyData(playerId)

    if not playerProperty then
        return false
    end

    -- Restrict by property type
    if playerProperty.type == 'apartment' and workbenchName == 'lvs_crafting_table_large' then
        return false
    end

    -- Restrict by property ID (e.g., premium properties only)
    if playerProperty.id == 5 and workbenchName ~= 'lvs_crafting_table_basic' then
        return false
    end

    -- Use extra data for additional checks
    if extra and extra.isRented then
        return false -- Don't allow placing in rented properties
    end

    return true
end
```

#### Related Events

* **`lvs_bridge:server:enterProperty`**: Event that sends property information including the `extra` parameter used in this function

#### Notes

* The `extra` parameter contains additional data that may have been sent when entering the property
* Customize this function to implement your own server-specific restrictions
* The function
