Electus Heists Exports
Exports for integrating Electus Heists with your own FiveM scripts, with parameters and usage.
Client Exports
useScuba
Use the configured scuba item behavior from another resource.
exports["electus_heists"]:useScuba()useCameraScanner
Start the configured camera scanner behavior.
exports["electus_heists"]:useCameraScanner()EMP and jammer item exports
Trigger the configured EMP or signal jammer behavior from another resource.
exports["electus_heists"]:useWeakEMP()
exports["electus_heists"]:useStrongEMP()
exports["electus_heists"]:useWeakSignalJammer()
exports["electus_heists"]:useStrongSignalJammer()Server Exports
These XP exports accept a player server ID and an XP type. The XP type is a name from Config.SkillLevels, such as hacking, lockpicking, electronics, or demolition. Use "contract" for contract rank XP.
| Parameter | Type | Description |
|---|---|---|
| source | number | The player's server ID. |
| xpType | string | A configured skill name or "contract". Names are case-sensitive. |
| amount | number | XP to add or remove. Must be finite and greater than zero after rounding down to an integer. Used by IncreaseXP and LowerXP. |
IncreaseXP
Add XP to the selected skill or contract rank. XP carries into subsequent levels until the configured skill maximum is reached. At the maximum skill level, remaining XP is discarded. Contract ranks have no maximum level.
---@type { level: number, xp: number, maxXp: number }|false
local levelData
---@type string?
local errorReason
levelData, errorReason = exports["electus_heists"]:IncreaseXP(source, "hacking", 100)Returns the updated level data. Adding contract XP also sends the contract XP notification and grants one skill-tree point per rank gained.
LowerXP
Remove XP from the selected skill or contract rank. If the amount exceeds the current level's XP, removal continues through earlier levels using their configured XP requirements. The minimum is level 1 with 0 XP.
---@type { level: number, xp: number, maxXp: number }|false
local levelData
---@type string?
local errorReason
levelData, errorReason = exports["electus_heists"]:LowerXP(source, "hacking", 50)Returns the updated level data. Losing contract ranks also removes one available skill-tree point per rank lost, down to zero available points. Existing skill-tree unlocks remain unlocked.
GetXP
Return XP within the current level. This value excludes XP spent reaching earlier levels. A player with no saved progression has 0 XP.
---@type number|false
local xp
---@type string?
local errorReason
xp, errorReason = exports["electus_heists"]:GetXP(source, "hacking")GetLevel
Return the current skill level or contract rank. A player with no saved progression starts at level 1.
---@type number|false
local level
---@type string?
local errorReason
level, errorReason = exports["electus_heists"]:GetLevel(source, "hacking")Level data
IncreaseXP and LowerXP return a table on success:
| Field | Type | Description |
|---|---|---|
| level | number | The updated skill level or contract rank. |
| xp | number | XP within the updated level. |
| maxXp | number | The configured XP requirement for the updated level. At a skill's maximum level, this value still reports the requirement, but further XP does not advance the skill. |
Errors
All four exports return false, "identifier_missing" when the player has no available identifier. IncreaseXP and LowerXP return false, "xp_update_failed" if the progression function does not return updated level data.
Missing or unknown XP types raise an assertion error. Invalid XP amounts also raise an assertion error.
Heist integration exports
All exports below run on the server and use PascalCase. Call them from a server script in another resource. Start operations can yield while waiting for database queries or police approval.
sourceis an online player's server ID.heistIdis the positive integer ID of the saved heist template.runtimeIdidentifies one running instance. Use the value returned byStartHeist,GetActiveHeists, orGetPlayerHeists; it can be a number or a string. A template can have multiple running instances.- Expected failures return
false, reason. Invalid configuration names, invalid IDs/options for start/status calls, and invalid amounts raise assertion errors.
GetActiveHeists
---@type HeistExportSummary[]
local heists = exports["electus_heists"]:GetActiveHeists()Returns an array of runtime summaries, including preloaded static heists and contract setups. Returns an empty array when nothing is loaded. The returned tables are snapshots; modifying them does not change a heist.
GetPlayerHeists
---@type HeistExportSummary[]|false
local heists
---@type string?
local reason
heists, reason = exports["electus_heists"]:GetPlayerHeists(source)Returns summaries for runtimes the player participates in, or an empty array. Contract participation follows the runtime's participant roster. Static participation means the player has actually interacted with that runtime since it loaded; merely being online does not count. A missing player identifier returns false, "identifier_missing".
IsPlayerInHeist
---@type boolean
local participating
---@type string?
local reason
participating, reason = exports["electus_heists"]:IsPlayerInHeist(source, runtimeId)Uses the same participation rules as GetPlayerHeists. Returns false without a reason for a valid runtime the player has not joined. Returns false, "heist_not_active" for a missing runtime or false, "identifier_missing" for an unavailable player identifier.
GetHeistParticipants
---@type number[]|false
local participants
---@type string?
local reason
participants, reason = exports["electus_heists"]:GetHeistParticipants(runtimeId)Returns a sorted, deduplicated array of online player server IDs. Static heists include actual interactors only. Disconnected players are excluded, and reconnected players are resolved by their character identifier. A missing runtime returns false, "heist_not_active".
Runtime summary
The HeistExportSummary type is defined in shared/export_types.lua.
| Field | Type | Description |
|---|---|---|
| runtimeId | number or string | Exact instance ID for participation and stop calls. |
| heistId | number | Saved template ID. |
| name | string | Internal heist name. |
| displayName | string or nil | Configured display name. |
| type | string | Heist type, normally contract or static. |
| interiorId | number or nil | Saved placement ID; nil for the base placement. |
| activeHeistId | number or nil | Purchased contract ID, also present for setups. |
| setupId | number or nil | Setup ID when this runtime is a setup. |
| started | boolean | Whether gameplay has started. Preloaded static heists return false. |
| completed | boolean | Whether the graph or finish conditions have completed. |
| activatedAt | number or nil | Runtime load time as Unix seconds. |
| lastInteractionAt | number or nil | Last recorded gameplay interaction as Unix seconds. |
| participants | number array | Online participants, using the rules above. |
GetHeistStatus
---@type HeistExportStatus|false
local status
---@type string?
local reason
status, reason = exports["electus_heists"]:GetHeistStatus(heistId)Returns the existing runtime status aggregated for a saved template. An existing template with no loaded instances returns a stopped status. An unknown template returns false, "heist_not_found".
| Field | Type | Description |
|---|---|---|
| runtimeActive | boolean | At least one instance is loaded. |
| runtimeActiveCount | number | Number of loaded instances. |
| isLive | boolean | Whether the status reports live gameplay. |
| runtimeState | string | stopped, loaded, live, or idle. |
| idleAt | number or nil | Idle deadline as Unix seconds, if configured. |
| idleRemainingSeconds | number or nil | Seconds remaining until that deadline, clamped to zero. |
Contract status reports live if any instance is live and uses the earliest idle deadline. Static status follows the first loaded placement; use GetActiveHeists to inspect each placement. Idle timing is not a purchase cooldown or a reservation.
CanStartHeist
---@type boolean
local canStart
---@type string?
local reason
canStart, reason = exports["electus_heists"]:CanStartHeist(source, heistId)Checks whether the player can currently start the heist. Accepts the same optional third argument as StartHeist. It does not purchase a contract, reserve an interior, start gameplay, stop overlapping runtimes, or request police approval. A successful check does not guarantee a later start; StartHeist checks again.
For contracts, the player must own a purchased contract with a ready crew and completed setups. The checks also cover enabled state, rank, gang membership, online ready crew members, police count, heat, placement availability, and overlap conflicts. Item and payment requirements are handled when purchasing the contract; they are not charged again.
For static heists, checks cover enabled state, rank, gang membership, police count, the player's heat, and the selected placement. A preloaded placement can start; a placement already marked started returns already_active.
StartHeist
---@type number|string|false
local runtimeId
---@type string?
local reason
runtimeId, reason = exports["electus_heists"]:StartHeist(source, heistId, {
activeHeistId = activeHeistId,
})
if runtimeId == false then
print(("Could not start heist: %s"):format(reason))
endReturns the started runtime ID on success, or false, reason. It uses the same contract start path as the built-in UI, including police approval when configured. Requirements are checked again after waiting for approval. Successful starts apply configured start heat; successful contract starts consume the purchased active-contract record.
| Option | Type | Description |
|---|---|---|
| activeHeistId | number, optional | Purchased contract owned by source. When omitted, the player's owned contract for this template is selected. Only valid for contract heists. |
| interiorId | number, optional | Specific saved placement belonging to this template. Contracts otherwise select an available saved placement, falling back to base. Static heists otherwise use base. |
The options table itself is optional. Other option keys raise an assertion error. There are no options to skip purchase, crew, setup, police, or heat requirements.
A preloaded static placement is marked started without replaying its load-time start nodes. An unloaded placement is activated normally. This export starts the main contract heist; it does not launch or complete setup missions.
StopHeist
---@type boolean
local stopped
---@type string?
local reason
stopped, reason = exports["electus_heists"]:StopHeist(runtimeId)Stops exactly one runtime and runs the normal entity, interaction, and state cleanup. Returns true on success or false, "heist_not_active" if the instance does not exist. It does not complete the heist, award rewards, or refund a consumed contract.
Other placements are not stopped. Stopping a static instance also sets the template's manual-stop flag, preventing automatic reload once no placements remain. An explicit successful StartHeist clears that flag.
Start failure reasons
| Reason | Meaning |
|---|---|
| identifier_missing | The player identifier is unavailable. |
| heist_not_found | The saved template does not exist. |
| heist_disabled | The template is inactive. |
| unsupported_heist_type | The template is neither static nor contract. |
| gang_required | The player does not meet the gang requirement. |
| required_level_missing | Contract rank is below the configured requirement. |
| contract_not_found | No matching purchased contract belongs to this player. |
| not_contract | An active contract ID was supplied for a static heist. |
| crew_not_ready | The crew is missing or too few current crew members are online and ready. |
| setups_incomplete | Required setup missions are incomplete. |
| not_enough_police | Online police count is too low. |
| heat_too_high | A checked player's heat is too high. |
| interior_not_found | The selected placement does not belong to this template. |
| already_active | The contract runtime or selected static placement has already started. |
| placement_unavailable | No eligible placement is available. |
| overlap_blocked | Another runtime blocks the overlap group. |
| start_in_progress | Another start for this template is pending. Returned by StartHeist. |
| police_rejected | Police rejected the start request. Returned by StartHeist. |
| police_approval_timeout | Police approval timed out. Returned by StartHeist. |
| start_failed | Activation failed after validation, for example because availability changed. Returned by StartHeist. |
Skill integration exports
These exports accept a player server ID. All return false, "identifier_missing" when the player identifier is unavailable and use the editable progression functions in server/progression.lua.
GetSkillLevels
---@type table<string, number>|false
local levels = exports["electus_heists"]:GetSkillLevels(source)Returns configured skill names mapped to their current levels, such as levels.hacking. Skills without saved progression start at level 1. Contract rank is excluded; use GetRank for that.
GetSkillTreePoints
---@type number|false
local points = exports["electus_heists"]:GetSkillTreePoints(source)Returns unspent skill-tree points. Players without saved points return zero.
AddSkillTreePoints
---@type number|false
local points = exports["electus_heists"]:AddSkillTreePoints(source, 2)Adds points and returns the updated unspent total. The amount must be finite and greater than zero after rounding down. It does not increase rank or unlock nodes automatically.
HasSkillUnlocked
---@type boolean
local unlocked
---@type string?
local reason
unlocked, reason = exports["electus_heists"]:HasSkillUnlocked(source, treeName, nodeId)Returns whether a configured node is unlocked, using the same rules as the skill-tree UI. Root nodes are implicitly unlocked. treeName must name a registered tree, and nodeId must be the full generated node ID, including parent names. Unknown trees or nodes raise assertion errors. A valid locked node returns false without a reason.
Heat and rank exports
SetHeat
---@type number|false
local heat
---@type string?
local reason
heat, reason = exports["electus_heists"]:SetHeat(source, 0)Sets the player's heat and returns the saved value. Accepts a finite, non-negative number, rounds down, and clamps to Config.Heat.maxHeat. Zero resets heat. Returns false, "identifier_missing" if the player identifier is unavailable. Invalid amounts raise assertion errors.
PascalCase heat and rank aliases
| Export | Return value |
|---|---|
IncreaseHeat(source, amount) | Updated heat after adding a positive amount. |
LowerHeat(source, amount) | Updated heat after subtracting a positive amount, down to zero. |
GetHeat(source) | Current heat with configured decay applied. |
IncreaseRankXP(source, amount) | Updated level data after adding contract XP. |
LowerRankXP(source, amount) | Updated level data after removing contract XP. |
GetRank(source) | Current contract rank. |
GetRankXP(source) | Contract XP within the current rank. |
Amounts use the same positive, finite, rounded-down validation as IncreaseXP. These exports return false, "identifier_missing" when no identifier is available. Rank mutation exports can also return false, "rank_update_failed" if the progression function returns no data. Rank changes update unspent skill-tree points using the rules described above for XP exports.
The original names increaseHeat, lowerHeat, getHeat, increaseRankXP, lowerRankXP, getRank, and getRankXP remain available for existing integrations.
Server lifecycle events
| Event | When it fires |
|---|---|
electus_heists:HeistStarted | Once per runtime when a contract starts, or when a static runtime first records a start/manual interaction. Preloading a static runtime alone does not fire it. |
electus_heists:HeistCompleted | Once per runtime when the graph or configured finish conditions record completion. |
electus_heists:HeistStopped | After the runtime is removed and normal cleanup finishes, including manual stops and resets. |
Each event passes a HeistExportSummary snapshot. Setup runtimes also emit these events; check summary.setupId to distinguish them from the main heist. Completion does not imply that the runtime has stopped or that all reward processing has finished. A stopped event contains the snapshot captured before cleanup.
---@param summary HeistExportSummary
AddEventHandler("electus_heists:HeistCompleted", function(summary)
if summary.setupId then return end
print(("Heist %s completed in runtime %s"):format(summary.heistId, summary.runtimeId))
end)Use AddEventHandler on the server. These are local server events and are not registered as client-callable network events.