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

# Exports

All exports are used in client

All exports of tgiann-core, grouped by side. Every export is registered under both casings of its first letter (`GetCore` and `getCore` both work), the docs use the uppercase form. `tgiCore = exports["tgiann-core"]:GetCore()` gives you the full API table with many more functions, the exports below are the ones you can call directly on the resource.

## Shared (client & server)

### GetCore

Returns the `tgiCore` API table (framework bridge + helpers). Returns nil until the core finished loading.

```lua
tgiCore = exports["tgiann-core"]:GetCore()
```

#### Returns

* `table` the tgiCore API table, or nil while the core is still starting

***

### GetConfig

Returns the shared core config table.

```lua
config = exports["tgiann-core"]:GetConfig()
```

#### Returns

* `table` the shared `config` table (lang, locale, framework detection, colors)

***

### ScriptIsStarted

Checks whether a resource is started. With `alreadyStart` it keeps erroring in console until the script is started.

```lua
local started = exports["tgiann-core"]:ScriptIsStarted("tgiann-inventory")
```

#### Parameters

* **scriptName**: `string` resource name to check
* **alreadyStart?**: `boolean` true = spam an error while the script is not started

#### Returns

* `boolean` whether the resource is started

***

### GetDarkMode

Returns the current dark mode state of the core glass UIs.

```lua
local dark = exports["tgiann-core"]:GetDarkMode()
```

#### Returns

* `boolean` current dark mode state

***

### SetDarkMode

Sets the dark mode state of the core glass UIs (menu, text ui, input menu).

```lua
exports["tgiann-core"]:SetDarkMode(true)
```

#### Parameters

* **state**: `boolean` true = dark mode on

***

### ChangeLanguage

Changes the active language of every tgiann script for this player and saves it. Client side.

```lua
exports["tgiann-core"]:ChangeLanguage("en")
```

#### Parameters

* **newLang**: `string` language code that exists in `configCore.langs`

***

### GetItemImageUrl

Item picture url of the server from `config.itemImages` (`"auto"` = the installed inventory). Every tgiann script shows item pictures with it.

```lua
local url = exports["tgiann-core"]:GetItemImageUrl():gsub("{item}", "water")
```

#### Returns

* `string` url with `{item}` = item name, e.g. `https://cfx-nui-inventory_images/images/{item}.webp`

***

### GetItemImageLocation

Picture folder and default file extension, for scripts that show an item's own image file (`nui://<location>/<file>`). Needs a `https://cfx-nui-<resource>/...` url in `config.itemImages`.

```lua
local location, extension = exports["tgiann-core"]:GetItemImageLocation()
```

#### Returns

* `string` `"<resource>/<path>"`, e.g. `"inventory_images/images"`
* `string` extension of a picture named after the item, e.g. `".webp"`

***

### GetVehicleImageUrl

Vehicle picture url of the server from `config.vehicleImages` (`resource` + `folder`). Every tgiann script shows vehicle pictures with it and tgiann-media-lib saves its local vehicle pictures there.

```lua
local url = exports["tgiann-core"]:GetVehicleImageUrl():format("adder")
```

#### Returns

* `string` url with `%s` = spawn name, e.g. `https://cfx-nui-tgiann-vehicle-images/images/%s.webp`

***

### Export

A global helper function, not an export you call on tgiann-core. Import the file into your own script's fxmanifest and every export you register with it works under both casings. The file runs inside your resource, so the export is registered on your script.

```lua
-- fxmanifest.lua of your script
shared_scripts {
    "@tgiann-core/shared/functions/export.lua",
    -- your other shared scripts
}
```

```lua
Export("RepairVehicle", function(vehicle)
    -- exports["my-script"]:RepairVehicle(veh) and exports["my-script"]:repairVehicle(veh) both work
end)
```

#### Parameters

* **name**: `string` export name
* **fn**: `function` the export function

## Client

### GetPlayerData

Refreshes and returns the framework player data of the local player.

```lua
local playerData = exports["tgiann-core"]:GetPlayerData()
```

#### Returns

* `table` framework player data (ESX PlayerData / QB PlayerData)

***

### GetPoliceCount

Returns how many players with a `config.policeJobs` job are online.

```lua
local count = exports["tgiann-core"]:GetPoliceCount()
```

#### Returns

* `number` online police count

***

### GetItemImage

Picture url of one item: its own image file from the item list, else the item name with the picture extension of `config.itemImages`.

```lua
local url = exports["tgiann-core"]:GetItemImage("water")
```

#### Parameters

* **itemName**: `string` item name

#### Returns

* `string` picture url

***

### AddDrawTextUi

Registers a "press E here" interaction point with distance, job, duty, ownable and custom checks. Becomes an ox\_target zone instead when `configCore.textUiAsTarget` is true.

```lua
exports["tgiann-core"]:AddDrawTextUi({
    name = "myShop",
    button = "E",
    text = "Open Shop",
    coords = vector3(25.7, -1347.3, 29.49),
    maxDistance = 15.0,
    pressDistance = 2.0,
    event = "myscript:client:openShop",
})
```

#### Parameters

* **data**: `table` point definition: `name`, `button`, `text` (string or `{ en = ..., tr = ... }`), `coords`, `maxDistance`, `pressDistance`, `car?`, `job?`/`jobs?`, `gang?`/`gangs?`, `grade?`, `duty?`, `boss?`, `playerOwnable?` (keyName), `canShow?` (function), `event?` + `data?`, `onPressed?` (function), `drawMarker?`

***

### RemoveDrawTextUi

Removes an interaction point by its name.

```lua
exports["tgiann-core"]:RemoveDrawTextUi("myShop")
```

#### Parameters

* **name**: `string` point name

***

### UpdateDrawTextUi

Patches fields of an existing interaction point.

```lua
exports["tgiann-core"]:UpdateDrawTextUi("myShop", { text = "Open Warehouse" })
```

#### Parameters

* **name**: `string` point name
* **patch**: `table` fields to merge into the point

***

### ContextOpen

Manually shows a text ui prompt (eg: `E | Open Shop`) without registering a point. Alias: `DrawTextOpen`.

```lua
exports["tgiann-core"]:ContextOpen("myPrompt", "E", "Open Shop")
```

#### Parameters

* **name**: `string` unique prompt name
* **button**: `string` key label
* **text**: `string` prompt text

#### Returns

* `boolean` whether the prompt was shown

***

### ContextClose

Hides a prompt opened with `ContextOpen`. Alias: `DrawTextClose`.

```lua
exports["tgiann-core"]:ContextClose("myPrompt")
```

#### Parameters

* **name**: `string` prompt name

***

### UiDrawText3D

NUI based 3d key prompt at a world position. Call it every tick, it hides itself about 100ms after the last call. Alias: `DrawText3D`.

```lua
CreateThread(function()
    while true do
        exports["tgiann-core"]:UiDrawText3D(coords, {
            { "E", "Open" },
            { "H", "Lock" },
        }, "myKey")
        Wait(0)
    end
end)
```

#### Parameters

* **coord**: `vector3` world position
* **data**: `table` rows, each row is `{ keyOrIcon, label }`
* **key?**: `string` id for this prompt, default `"1"`, namespaced per resource

#### Returns

* `boolean` false when the pause menu is open or the point is off screen

***

### CloseUiDrawText

Hides a 3d prompt immediately instead of waiting for the auto-hide.

```lua
exports["tgiann-core"]:CloseUiDrawText("myKey")
```

#### Parameters

* **key?**: `string` prompt id

***

### OpenKeyHelpMenu

Shows the key help panel (list of key + label rows) on screen.

```lua
exports["tgiann-core"]:OpenKeyHelpMenu({
    { icon = "eKey", label = "Confirm" },
    { icon = "escKey", label = "Cancel" },
})
```

#### Parameters

* **rows**: `table` rows of `{ icon, label }`; icon is a key icon name (`eKey`, `enterKey`, `escKey`, `mouseLeftClick`...) or a list of them

***

### CloseKeyHelpMenu

Closes the key help panel.

```lua
exports["tgiann-core"]:CloseKeyHelpMenu()
```

***

### Menu

Returns the core menu registry (same table as `tgiCore.UI.Menu`) with `Open`, `Close`, `CloseAll`, `IsOpen`, `RegisterType` and more.

```lua
exports["tgiann-core"]:Menu().Open("default", "shop", "main",
    { title = "Shop", elements = { { label = "Buy", value = "buy" } } },
    function(res, menu)
        print(res.current.value)
        menu.close()
    end)
```

#### Returns

* `table` the menu registry

***

### UseGizmo

Opens the gizmo on an entity for interactive placement. Blocks until the player confirms or cancels. One gizmo at a time.

```lua
local result = exports["tgiann-core"]:UseGizmo(entity)
if result.success then
    print(result.position, result.rotation)
end
```

#### Parameters

* **entity**: `number` entity to move/rotate
* **gizmoData?**: `table` options: `disables?`, `maxDistance?`, `customSnapGround?`, `camera?`, `keys?`

#### Returns

* `table` `{ handle, success, model, position, rotation }`

***

### FinishGizmo

Ends the active gizmo from code, as if the player confirmed or cancelled.

```lua
exports["tgiann-core"]:FinishGizmo(true)
```

#### Parameters

* **success**: `boolean` true = confirm, false = cancel

***

### CreateCam

Creates an orbit/focus camera and returns its controller. See the camera methods on `cam.Function` (attach, zoom, rotate, dof, destroy...).

```lua
local cam = exports["tgiann-core"]:CreateCam({ coords = coords, focusEntity = vehicle, zoom = 50.0 }, "myCam")
cam.Function.Destroy(500)
```

#### Parameters

* **data**: `table` `{ coords, heading?, time?, focusEntity?, zoom?, height?, distance?, minHeight?, maxDegree? }`
* **id?**: `string` camera id, random when omitted

#### Returns

* `table` camera object with `Function` methods

***

### GetCam

Returns a camera created with `CreateCam` by its id.

```lua
local cam = exports["tgiann-core"]:GetCam("myCam")
```

#### Parameters

* **id**: `string` camera id

#### Returns

* `table` camera object or nil

***

### CreateFreeCam

Starts a WASD fly camera (single instance). Returns the instance with `Function.GetCoords/SetCoords/SetSpeed/Destroy`.

```lua
local fc = exports["tgiann-core"]:CreateFreeCam({ speed = 0.2, scroll = "zoom" })
```

#### Parameters

* **data?**: `table` options: `coords?`, `pitch?`, `heading?`, `speed?`, `fov?`, `scroll?`, `canMove?`, `lookButton?`, `freezePlayer?`, `transition?`, `maxDistance?`, `onMove?`, `onDestroy?` and more

#### Returns

* `table` free cam instance

***

### GetFreeCam

Returns the active free cam instance or nil.

```lua
local fc = exports["tgiann-core"]:GetFreeCam()
```

#### Returns

* `table` active instance or nil

***

### DestroyFreeCam

Destroys the active free cam.

```lua
exports["tgiann-core"]:DestroyFreeCam(500)
```

#### Parameters

* **transitionTime?**: `number` ms of the blend back to gameplay

***

### AddTargetSphereZone

Adds a sphere target zone through the ox\_target / qb-target bridge. Zones of a resource are cleaned automatically when it stops.

```lua
local id = exports["tgiann-core"]:AddTargetSphereZone({
    coords = coords,
    radius = 1.5,
    options = {
        { label = "Open", icon = "fas fa-box", onSelect = function() print("open") end },
    },
})
```

#### Parameters

* **data**: `table` `{ coords, name?, radius?, debug?, drawSprite?, options }`; options are ox-style target options (`label`, `icon?`, `distance?`, `job?`, `canInteract?`, `onSelect?`, `event?`, `serverEvent?`...)

#### Returns

* `string` zone id

***

### RemoveTargetZone

Removes a target zone by the id or name it was created with.

```lua
exports["tgiann-core"]:RemoveTargetZone(id)
```

#### Parameters

* **idOrName**: `string` zone id or name

***

### AddTargetModel

Adds target options to one or more models.

```lua
exports["tgiann-core"]:AddTargetModel("prop_atm_01", {
    { label = "Use ATM", event = "myscript:client:atm" },
})
```

#### Parameters

* **models**: `string | number | table` model name/hash or a list of them
* **options**: `table` ox-style target options

***

### AddLocalEntity

Adds target options to specific entity handles.

```lua
exports["tgiann-core"]:AddLocalEntity(entity, {
    { label = "Inspect", onSelect = function(data) print(data.entity) end },
})
```

#### Parameters

* **entities**: `number | table` entity handle or a list of them
* **options**: `table` ox-style target options

***

### CreateDistanceProps

Registers a pool of local (never networked) props that spawn when the player is close and despawn when far. The entry list is re-read every interval, so live config edits apply.

```lua
exports["tgiann-core"]:CreateDistanceProps({
    getEntries = function()
        return {
            { key = "shop:1", model = "prop_atm_01", coord = vector3(0, 0, 72.0), heading = 90.0,
              onSpawn = function(object) end },
        }
    end,
    spawnDistance = 100.0,
    interval = 2000,
})
```

#### Parameters

* **data**: `table` `{ getEntries, spawnDistance?, interval? }`; each entry is `{ key, model, coord, heading?, onSpawn? }`

***

### SetDistancePropHiddenCoord

Hides the prop at a coordinate in every distance pool, used while a creator/gizmo edits that point.

```lua
exports["tgiann-core"]:SetDistancePropHiddenCoord(coords)
```

#### Parameters

* **coord**: `vector3 | nil` coordinate to hide, nil to show everything again

***

### Pedcreate

Registers a managed static ped that spawns within 300 units and despawns when far. The ped is frozen and invincible.

```lua
exports["tgiann-core"]:Pedcreate("shopkeeper", `mp_m_shopkeep_01`, 25.7, -1347.3, 29.49, 180.0)
```

#### Parameters

* **name**: `string` unique ped name
* **hash**: `number` ped model hash
* **x**: `number` position x
* **y**: `number` position y
* **z**: `number` position z
* **h**: `number` heading

***

### Peddelete

Removes a managed ped by its name.

```lua
exports["tgiann-core"]:Peddelete("shopkeeper")
```

#### Parameters

* **name**: `string` ped name

***

### IsCreatedPed

Checks whether an entity is one of the managed peds.

```lua
local isManaged = exports["tgiann-core"]:IsCreatedPed(ped)
```

#### Parameters

* **ped**: `number` entity handle

#### Returns

* `boolean` whether the ped was created by `Pedcreate`

***

### FreezeTime

Freezes the game clock, optionally at a given time. Auto-disables common weather sync scripts while overriding.

```lua
exports["tgiann-core"]:FreezeTime(12, 0)
```

#### Parameters

* **hour?**: `number` hour to freeze at
* **minute?**: `number` minute to freeze at

***

### StartTime

Restores normal time sync after `FreezeTime`/`SetTime`.

```lua
exports["tgiann-core"]:StartTime()
```

***

### SetTime

Sets the game clock.

```lua
exports["tgiann-core"]:SetTime(22, 30)
```

#### Parameters

* **hour**: `number` hour
* **minute**: `number` minute

***

### SetWeather

Overrides the weather.

```lua
exports["tgiann-core"]:SetWeather("THUNDER")
```

#### Parameters

* **weather?**: `string` weather type, default `EXTRASUNNY`

***

### SetPlayerRoutingBucket (client)

Moves the local player (and optionally their vehicle) to a routing bucket.

```lua
local ok = exports["tgiann-core"]:SetPlayerRoutingBucket(2, vehicle)
```

#### Parameters

* **bucket**: `number` routing bucket id, 0 = default world
* **vehicle?**: `number` vehicle to move together with the player

#### Returns

* `boolean` success

***

### SetEntityRoutingBucket (client)

Moves an entity to a routing bucket.

```lua
local ok = exports["tgiann-core"]:SetEntityRoutingBucket(2, entity)
```

#### Parameters

* **bucket**: `number` routing bucket id
* **entity**: `number` entity handle

#### Returns

* `boolean` success

***

### StartZoneCreator

Opens the in-game zone/point creator (used by tgiann admin panels) and returns the created shape when the player finishes.

```lua
local result = exports["tgiann-core"]:StartZoneCreator({ mode = "polygon" })
```

#### Parameters

* **data**: `table` `{ mode? = "point" | "points4" | "polygon", maxDistance?, ... }` creator options

#### Returns

* `table` created zone/point data, or nil when a creator is already active or the player cancels

***

### PlayerHasOwnable

Returns whether the local player owns a business (or works there with `includeEmployee`).

```lua
local isMine = exports["tgiann-core"]:PlayerHasOwnable("mechanic_lsc", true)
```

#### Parameters

* **keyName**: `string` business key
* **includeEmployee?**: `boolean` true = employees count too

#### Returns

* `boolean` whether the player owns/works at the business

***

### GetPlayerControlPanelKeyNames (client)

Returns the local player's businesses as `{ [keyName] = { owner = boolean } }`.

```lua
local list = exports["tgiann-core"]:GetPlayerControlPanelKeyNames(true)
```

#### Parameters

* **includeEmployee?**: `boolean` include businesses the player works at

#### Returns

* `table` keyName keyed table with `{ owner = boolean }`

***

### CanBuyOwnable

Returns whether a business is currently for sale (`canBuy` was not disabled).

```lua
local canBuy = exports["tgiann-core"]:CanBuyOwnable("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

#### Returns

* `boolean` whether the business can be bought

***

### IsOwnableBought

Returns whether a business currently has an owner.

```lua
local bought = exports["tgiann-core"]:IsOwnableBought("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

#### Returns

* `boolean` whether the business is bought

***

### IsOwnablePanelVisible

Returns whether the boss panel marker/prompt of a business should be visible to this player (owner, or unsold and buyable).

```lua
local visible = exports["tgiann-core"]:IsOwnablePanelVisible("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

#### Returns

* `boolean` whether the panel should be shown

***

### RegisterPlayerOwnablePanel

Registers the boss/buy interaction point of a business in the world.

```lua
exports["tgiann-core"]:RegisterPlayerOwnablePanel({
    keyName = "mechanic_lsc",
    coords = vector3(-347.3, -133.5, 39.0),
    ownerPanelText = "Mechanic Shop",
})
```

#### Parameters

* **data**: `table` `{ keyName, coords, ownerPanelText, disableDrawMarker?, drawMarkerDist? }`

***

### RemovePlayerOwnablePanel

Removes a registered boss panel point.

```lua
exports["tgiann-core"]:RemovePlayerOwnablePanel("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

***

### UpdatePlayerOwnablePanel

Updates fields of a registered boss panel point (e.g. move its coords).

```lua
exports["tgiann-core"]:UpdatePlayerOwnablePanel("mechanic_lsc", "coords", newCoords)
```

#### Parameters

* **keyName**: `string` business key
* **dataKey**: `string | table` field name, or a field -> value table
* **dataValue?**: `any` value when dataKey is a field name

***

### OpenPlayerOwnableBossMenu

Opens the built-in boss menu of a business: the buy screen for strangers, the owner menu (money, rent, employees, transfer, sell back) for the owner.

```lua
exports["tgiann-core"]:OpenPlayerOwnableBossMenu("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

## Server

### CreateControlPanel

Registers or updates a buyable business. Idempotent, call it every script start. The calling resource is stamped on the panel and used by the per-script ownable limits in `configCore.playerOwnableLimits`.

```lua
exports["tgiann-core"]:CreateControlPanel({
    keyName = "mechanic_lsc",
    price = 500000,
    priceType = "bank",
    rentMoneyPercent = 0.1,
    rentPeriodDay = 7,
    rentPayBeforeDay = 2,
    canHireEmployee = true,
    maxEmployee = 5,
    coords = vector3(-347.3, -133.5, 39.0),
})
```

#### Parameters

* **data**: `table` `keyName` (required, unique), `price`, `priceType?` (`"bank"` default), `priceSymbol?`, `rentMoneyPercent`, `rentPeriodDay`, `rentPayBeforeDay`, `canHireEmployee?`, `maxEmployee?`, `changeJob?` (`{ name, bossGrade?, employeeGrade?, onDuty? }`), `canBuy?`, `canTransfer?` (default true), `canSellBack?` (default true), `rentUnlimited?` (true = no rent, never expires), `noMoneyMsg?`, `tgiannShopData?`, `coords`

#### Returns

* `table` the panel object

***

### RegisterOwnableHook / RemoveOwnableHooks

Hooks of the business system (pre, query and post hooks with every payload and an example each) are documented on the [Hooks](/tgiann/scripts/tgiann-core/hooks.md) page.

```lua
local hookId = exports["tgiann-core"]:RegisterOwnableHook("businessBuy", function(payload)
    if payload.price > 1000000 then return false end -- cancels the purchase
end, { keyFilter = { mechanic_lsc = true } })

exports["tgiann-core"]:RemoveOwnableHooks(hookId)
```

***

### GetControlPanelData

Returns the current state of one business.

```lua
local panel = exports["tgiann-core"]:GetControlPanelData("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

#### Returns

* `table` panel data (`isBought`, `owner`, `money`, `price`, rent fields, `rentMultiplier` of the current rent cycle, `canTransfer`, `canSellBack`, `rentUnlimited`, `employeeList`, `ownerResource`...), or nil

***

### GetAllControlPanels

Returns every registered business keyed by keyName.

```lua
local panels = exports["tgiann-core"]:GetAllControlPanels()
```

#### Returns

* `table` keyName keyed panel data

***

### DeleteControlPanel

Removes a business: everyone loses it and its DB rows are cleared. Runs the `businessRemove` hook first, a hook returning `false` keeps the business.

```lua
local removed = exports["tgiann-core"]:DeleteControlPanel("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

#### Returns

* `boolean` `false` when a hook cancelled it, nil when the business does not exist

***

### UpdateControlPanelData

Updates one or more fields of a business.

```lua
exports["tgiann-core"]:UpdateControlPanelData("mechanic_lsc", "price", 750000)
```

#### Parameters

* **keyName**: `string` business key
* **dataKey**: `string | table` field name, or a field -> value table
* **dataValue?**: `any` value when dataKey is a field name

***

### ControlPanelAddMoney

Adds income to a business vault. Does nothing while the business has no owner. Runs the `businessAddMoney` hook first, then `businessBalanceChanged`.

```lua
local added = exports["tgiann-core"]:ControlPanelAddMoney("mechanic_lsc", 2500)
```

#### Parameters

* **keyName**: `string` business key
* **money**: `number` amount to add

#### Returns

* `boolean` `false` when a hook cancelled it, nil when the business does not exist

***

### ControlPanelRemoveMoney

Takes money out of a business vault. Fails when the business is not bought, the amount is not positive or the vault holds less. Runs the `businessRemoveMoney` hook first.

```lua
local removed = exports["tgiann-core"]:ControlPanelRemoveMoney("mechanic_lsc", 2500)
```

#### Parameters

* **keyName**: `string` business key
* **money**: `number` amount to remove

#### Returns

* `boolean` success

***

### ControlPanelBalance

Vault balance of a bought business.

```lua
local money = exports["tgiann-core"]:ControlPanelBalance("mechanic_lsc")
```

#### Parameters

* **keyName**: `string` business key

#### Returns

* `number?` nil when the business does not exist or is not bought

***

### ControlPanelBuy

Makes the player buy the business (charges them). Runs the same checks and hooks as the boss menu buy button, including the `businessRentPeriod` query for the first rent period.

```lua
local panel = exports["tgiann-core"]:ControlPanelBuy(src, "mechanic_lsc")
```

#### Parameters

* **src**: `number` player server id
* **keyName**: `string` business key

#### Returns

* `table | false` panel data on success

***

### ControlPanelGetMoney

Owner withdraws the full business balance as cash. Runs the `businessWithdraw` hook.

```lua
exports["tgiann-core"]:ControlPanelGetMoney(src, "mechanic_lsc")
```

#### Parameters

* **src**: `number` player server id, must be the owner
* **keyName**: `string` business key

#### Returns

* `table | false` panel data on success

***

### ControlPanelPayRent

Owner pays the rent and extends the rental period. The new period is `rentPeriodDay` times the `businessRentPeriod` multiplier of that player. Fails on `rentUnlimited` businesses. Runs the `businessPayRent` hook.

```lua
exports["tgiann-core"]:ControlPanelPayRent(src, "mechanic_lsc")
```

#### Parameters

* **src**: `number` player server id, must be the owner
* **keyName**: `string` business key

#### Returns

* `table | false` panel data on success

***

### ControlPanelSellBack

Owner gives the business back, same flow as the boss menu button: the `businessSellBack` hook runs, the vault money is lost and the business goes up for sale again.

```lua
exports["tgiann-core"]:ControlPanelSellBack(src, "mechanic_lsc")
```

#### Parameters

* **src**: `number` player server id, must be the owner
* **keyName**: `string` business key

***

### GetOwnableRentPeriod

Returns the rent period a player would get on buy / pay rent, resolved through the `businessRentPeriod` hooks. Use it to show the same numbers in your own UI (tgiann-shop does). Returns nil when the business does not exist or the ownable override is active.

```lua
local rentPeriod = exports["tgiann-core"]:GetOwnableRentPeriod("mechanic_lsc", citizenId)
-- rentPeriod.days = 14, rentPeriod.multiplier = 2, rentPeriod.label = "Subscriber bonus: 2x rent period"
```

#### Parameters

* **keyName**: `string` business key
* **citizenId**: `string` player identifier/citizenid
* **src?**: `number` player server id, resolved from citizenId when omitted

#### Returns

* `table` `{ multiplier, days, label? }`, or nil

***

### GetPlayerControlPanelKeyNames (server)

Returns a player's businesses as `{ [keyName] = { owner = boolean } }`.

```lua
local list = exports["tgiann-core"]:GetPlayerControlPanelKeyNames(citizenId, true)
```

#### Parameters

* **citizenId**: `string` player identifier/citizenid
* **includeEmployee?**: `boolean` include businesses the player works at

#### Returns

* `table` keyName keyed table with `{ owner = boolean }`

***

### GetControlPanelDataForPlayer

Returns the boss-menu view model for a player: buy screen data, owner menu data, or the "owned by someone else" state. `rentPeriodDay` on the buy screen and `nextRentPeriodDay` in the owner data already include the player's `businessRentPeriod` multiplier.

```lua
local result = exports["tgiann-core"]:GetControlPanelDataForPlayer(src, "mechanic_lsc")
```

#### Parameters

* **src**: `number` player server id
* **keyName**: `string` business key

#### Returns

* `table` `{ buyed, owner?, data?, price?, rentPeriodDay?, rentPeriodLabel?, rentUnlimited?, priceSymbol? }`; `data` carries the panel data plus `nextRentPeriodDay` and `rentPeriodLabel`

***

### IsPlayerInOwnableForJob

Checks whether a player is the owner or an employee of the business bound to a framework job.

```lua
local isMember, keyName, role = exports["tgiann-core"]:IsPlayerInOwnableForJob(citizenId, "mechanic")
```

#### Parameters

* **citizenId**: `string` player identifier/citizenid
* **jobName**: `string` framework job name

#### Returns

* `boolean` isMember
* `string` keyName of the business, when a member
* `string` `"owner"` or `"employee"`, when a member

***

### GetBusinessPurchases

Returns the last 100 business purchases of a player.

```lua
local purchases = exports["tgiann-core"]:GetBusinessPurchases(citizenId)
```

#### Parameters

* **citizenId**: `string` player identifier/citizenid

#### Returns

* `table` list of `{ id, citizenId, keyName, price, priceType, purchasedAt }`

***

### RequestBusinessTransfer

Starts a business transfer offer from the owner to another player, same flow as the boss menu transfer button. Blocked when the panel has `canTransfer = false` or a `businessTransferRequest` hook cancels it.

```lua
exports["tgiann-core"]:RequestBusinessTransfer(src, "mechanic_lsc", targetCitizenId, 250000)
```

#### Parameters

* **src**: `number` owner's server id
* **keyName**: `string` business key
* **targetCid**: `string` citizenid of the player receiving the offer
* **price**: `number` transfer price, 0 = free

***

### ControlPanelEmployeeAction

The owner at `src` hires or fires a player, for scripts with their own boss panel. Same checks, hooks and notifications as the employee buttons of the boss menu: employment limits, the unemployed rule of `changeJob` businesses, `businessHireEmployee` / `businessFireEmployee`. To add or remove someone without the owner, use `AddOwnableMember` / `RemoveOwnableMember`.

```lua
local ok = exports["tgiann-core"]:ControlPanelEmployeeAction(src, "mechanic_lsc", "add", targetCitizenId)
```

#### Parameters

* **src**: `number` server id of the owner
* **keyName**: `string` business key
* **action**: `"add" | "remove"` hire or fire
* **citizenId**: `string` citizenid of the employee; the player must be online to be hired

#### Returns

* `boolean` false when `src` is not the owner, a check failed or a hook cancelled it

***

### AddOwnableMember

Gives a business to a player without a purchase and without the owner, for admin tools and scripts. Same as the `addOwnableLocation` admin command.

* `"owner"`: an unsold business is opened for the player (no money is charged), an owned one is handed over and the old boss loses the `changeJob` job. Works for offline players too.
* `"employee"`: the player must be online. An unsold business is opened without a boss first.

Runs the pre hooks `businessBuy`, `businessTransfer` or `businessHireEmployee` with `price = 0`, `priceType = "admin"`, `admin = true` and `resource`. The ownable limits of `configCore.playerOwnableLimits` are not checked.

```lua
local ok, reason = exports["tgiann-core"]:AddOwnableMember("mechanic_lsc", citizenId, "employee")
if not ok then print("could not add:", reason) end
```

#### Parameters

* **keyName**: `string` business key
* **citizenId**: `string` player identifier/citizenid
* **role?**: `"owner" | "employee"` default `"owner"`

#### Returns

* `boolean` success
* `string?` why it failed: `"notFound"` (no such business), `"invalidRole"`, `"alreadyOwner"`, `"blocked"` (a hook cancelled it), `"noEmployee"` (`canHireEmployee` is off), `"maxEmployee"`, `"playerOffline"`, `"failed"` (already an employee or the owner)

***

### RemoveOwnableMember

Takes a player out of a business without the owner, for admin tools and scripts.

* Employee: removed like the boss menu fire button (`businessFireEmployee` hook), the `changeJob` job goes back to unemployed. When that was the last member of a business without a boss, the business closes.
* Owner: while the business has employees it stays open without a boss (owner `"0"`, `businessTransfer` hook with `toCitizenId = "0"`) and the player's `changeJob` job goes back to unemployed. Without employees the business is closed like `DeleteControlPanel` (`businessRemove` hook).

```lua
local ok, reason = exports["tgiann-core"]:RemoveOwnableMember("mechanic_lsc", citizenId)
```

#### Parameters

* **keyName**: `string` business key
* **citizenId**: `string` player identifier/citizenid

#### Returns

* `boolean` success
* `string?` why it failed: `"notFound"` (no such business), `"notMember"` (neither owner nor employee), `"blocked"` (a hook cancelled it)

***

### GetPlayerLang

Returns the saved language of a player.

```lua
local lang = exports["tgiann-core"]:GetPlayerLang(src)
```

#### Parameters

* **src**: `number` player server id

#### Returns

* `string` language code

***

### GetJobCount

Returns how many players of a job are online.

```lua
local count = exports["tgiann-core"]:GetJobCount("police", true)
```

#### Parameters

* **jobName**: `string | table` job name or a list of names
* **onlyOnDuty?**: `boolean` count only on-duty players

#### Returns

* `number` online player count

***

### GetJobPlayers

Returns the server ids of the online players of a job.

```lua
local players = exports["tgiann-core"]:GetJobPlayers("police", true)
```

#### Parameters

* **jobName**: `string | table` job name or a list of names
* **onlyOnDuty?**: `boolean` only on-duty players

#### Returns

* `table` server ids

***

### GetDiscordRoles

Returns a player's discord roles in the configured guild (`configCore.discordConfig`).

```lua
local roles, inGuild = exports["tgiann-core"]:GetDiscordRoles(src)
```

#### Parameters

* **src**: `number` player server id

#### Returns

* `table` role id list
* `boolean` whether the player is in the guild

***

### GetUserRolesInGuild

Returns a discord user's roles in any guild the bot is in.

```lua
local roles = exports["tgiann-core"]:GetUserRolesInGuild(userId, guildId)
```

#### Parameters

* **userId**: `string` discord user id
* **guildId**: `string` discord guild id

#### Returns

* `table` role id list

***

### SetPlayerRoutingBucket (server)

Moves a player (and optionally their vehicle) to a routing bucket.

```lua
local ok = exports["tgiann-core"]:SetPlayerRoutingBucket(src, 2, vehicleNetId)
```

#### Parameters

* **src**: `number` player server id
* **bucket**: `number` routing bucket id, 0 = default world
* **vehicleNetId?**: `number` vehicle to move together with the player

#### Returns

* `boolean` success

***

### SetEntityRoutingBucket (server)

Moves an entity to a routing bucket.

```lua
local ok = exports["tgiann-core"]:SetEntityRoutingBucket(2, entity)
```

#### Parameters

* **bucket**: `number` routing bucket id
* **entity**: `number` entity handle

#### Returns

* `boolean` success

***

### SetBucketDistance

Sets the culling radius of a routing bucket.

```lua
exports["tgiann-core"]:SetBucketDistance(2, 500.0)
```

#### Parameters

* **bucket**: `number` routing bucket id
* **distance**: `number` culling radius in meters

***

### CheckArtifactVersion

Checks the server artifact version and warns in console when it is a known broken build. Runs automatically when `configCore.checkArtifactVersion` is true.

```lua
exports["tgiann-core"]:CheckArtifactVersion()
```
