Browse docs

Client Exports

Client-side exports provided by the Sky Ambulancejob resource.

Radial Menu

getRadialActions()

  • Purpose: Provides the current list of radial menu actions along with labels, descriptions, and availability metadata.
  • Returns: RadialAction[] where each entry contains id, label, description, icon, available, and optional badge or helper fields.
local actions = exports["sky_ambulancejob"]:getRadialActions()

getRadialAction(actionId)

  • Purpose: Fetches a single action snapshot by actionId.
  • Arguments:
    • actionId (string)
  • Returns: The action snapshot or nil when missing.
local action = exports["sky_ambulancejob"]:getRadialAction("treat_patient")

getRadialActionReport()

  • Purpose: Bundles the action list with a quick lookup map for availability and reason information.
  • Returns: Object with actions and availability, where each key maps to available, disabledReasonKey, and disabledReason.
local report = exports["sky_ambulancejob"]:getRadialActionReport()

isRadialMenuActionAvailable(actionId)

  • Purpose: Tests if a radial menu action is currently enabled without opening the menu.
  • Arguments:
    • actionId (string)
  • Returns: boolean (true when the action exists and is enabled).
local available = exports["sky_ambulancejob"]:isRadialMenuActionAvailable("treat_patient")

triggerRadialMenuAction(actionId)

  • Purpose: Executes the same handler the radial menu would for the given action, without opening the UI.
  • Arguments:
    • actionId (string)
  • Returns:
    • boolean: true when the action was accepted.
    • table?: When the action fails, returns a map with key/fallback for notification text.
local success, err = exports["sky_ambulancejob"]:triggerRadialMenuAction("treat_patient")

Radial Menu Actions

Each action mirrors the descriptions and availability logic of the in-game radial UI.

Action IDIconLabelDescription
stretcher_deployBedDeploy / Stow stretcherDeploy or stow the stretcher from the assigned vehicle.
stretcher_carryHandPick up / Place stretcherPick up or place the active stretcher nearby.
stretcher_patientBedDoublePlace / Release patientMove patients on or off the active stretcher.
stretcher_vehicleTruckLoad / Unload stretcherMove the stretcher between the ground and the vehicle.
carry_patientHelpingHandCarry / Drop patientCarry the closest person to safety, or drop them.
vehicle_pullCarPull from vehiclePull an unconscious patient out of a nearby vehicle.
self_diagnoseUserRoundSearchSelf-diagnoseInspect and treat your own injuries.
treat_patientHeartPulseTreat patientDiagnose and treat the closest patient.
billingReceiptTextIssue billIssue a bill to the nearest patient.

Crutch

EquipCrutch()

  • Purpose: Equips a crutch on the local player.
exports["sky_ambulancejob"]:EquipCrutch()

UnequipCrutch()

  • Purpose: Removes the crutch from the local player.
exports["sky_ambulancejob"]:UnequipCrutch()

ToggleCrutch()

  • Purpose: Toggles the crutch on or off.
exports["sky_ambulancejob"]:ToggleCrutch()

SetWalkStyle(style)

  • Purpose: Sets the crutch walk animation style.
  • Arguments:
    • style (string): The clipset name for the walk animation.
exports["sky_ambulancejob"]:SetWalkStyle("move_m@injured")

Wheelchair

EquipWheelchair()

  • Purpose: Equips a wheelchair for the local player.
exports["sky_ambulancejob"]:EquipWheelchair()

UnequipWheelchair()

  • Purpose: Removes the wheelchair from the local player.
exports["sky_ambulancejob"]:UnequipWheelchair()

ToggleWheelchair()

  • Purpose: Toggles the wheelchair on or off.
exports["sky_ambulancejob"]:ToggleWheelchair()

Revive

revive(payload?)

  • Purpose: Revives the local player by sending a server-validated revive request. Only works when the player is currently dead.
  • Arguments:
    • payload (table?): Optional revive context.
      • reason (string?): Controls post-revive behaviour.
        • "command" — Admin/force revive. Skips the death timeout (combat lockout).
        • nil / omitted — Normal revive. Death timeout applies as configured.
-- Normal revive
exports["sky_ambulancejob"]:revive()

-- Admin revive (skips death timeout)
exports["sky_ambulancejob"]:revive({ reason = "command" })

Death Screen

open()

  • Purpose: Opens the death screen UI.
exports["sky_ambulancejob"]:open()

updateTime(seconds)

  • Purpose: Updates the bleed-out timer to a specific value.
  • Arguments:
    • seconds (number): The new timer value in seconds.
exports["sky_ambulancejob"]:updateTime(120)

addTime(seconds)

  • Purpose: Adds time to the current bleed-out timer.
  • Arguments:
    • seconds (number): Seconds to add.
exports["sky_ambulancejob"]:addTime(30)

AI Medic

setAiMedicState(state, reason?)

  • Purpose: Updates the AI medic status shown on the death screen UI. Use this when you override the built-in AI medic via Config.Functions.onAiMedicRequest and need to update the UI from your own system.
  • Arguments:
    • state (string): One of "idle", "requesting", "dispatched", "driving", "arrived", "reviving", "finished", "failed", "cooldown".
    • reason (string?): Optional failure reason when state is "failed""not_enough_money", "medics_online", "spawn_failed", "disabled".
-- Show "AI medic on the way"
exports["sky_ambulancejob"]:setAiMedicState("driving")

-- Show failure
exports["sky_ambulancejob"]:setAiMedicState("failed", "spawn_failed")

-- Reset to idle
exports["sky_ambulancejob"]:setAiMedicState("idle")

getAiMedicState()

  • Purpose: Returns the current AI medic state.
  • Returns: string — the current state (e.g. "idle", "driving", "reviving").
local state = exports["sky_ambulancejob"]:getAiMedicState()

isAiMedicActive()

  • Purpose: Checks if the AI medic is currently active or pending.
  • Returns: boolean
local active = exports["sky_ambulancejob"]:isAiMedicActive()
To override the built-in AI medic with your own system, use the Config.Functions.onAiMedicRequest hook in config/functions.lua. Return false to prevent the default AI medic from dispatching, then use the exports above to update the death screen UI.
-- config/functions.lua
Config.Functions.onAiMedicRequest = function()
    exports['my-medic-resource']:sendHelp()
    return false -- prevent built-in AI medic
end

Death Timeout

stopDeathTimeout()

  • Purpose: Immediately stops the active death timeout (combat lockout) for the local player.
exports["sky_ambulancejob"]:stopDeathTimeout()

setDeathTimeout(seconds)

  • Purpose: Sets or overrides the death timeout duration. Pass 0 to stop the current timeout.
  • Arguments:
    • seconds (number): Duration in seconds.
exports["sky_ambulancejob"]:setDeathTimeout(120)

getDeathTimeout()

  • Purpose: Returns the current death timeout state.
  • Returns: table with active (boolean) and remaining (number, seconds).
local state = exports["sky_ambulancejob"]:getDeathTimeout()
if state.active then
    print("Timeout remaining: " .. state.remaining .. "s")
end

Injury & State

GetLocalInjuryProfile()

  • Purpose: Returns the current player's injury profile with all active conditions and wounds.
  • Returns: table — the full injury profile object.
local profile = exports["sky_ambulancejob"]:GetLocalInjuryProfile()

isDead()

  • Purpose: Queries the local player's death state.
  • Returns: boolean (true when dead/downed, false when alive).
local dead = exports["sky_ambulancejob"]:isDead()

Self-Diagnose

OpenSelfDiagnose()

  • Purpose: Opens the full diagnose UI on the local player, allowing them to inspect and treat their own injuries. Requires Config.SelfDiagnose.enabled = true. When Config.SelfDiagnose.requireMedicJob is true (default), only on-duty medics can use this export.
  • Returns:
    • boolean: true when the diagnose UI was opened successfully.
    • string?: Reason when the call fails — "disabled", "no_permission", "busy", "dead".
local success, reason = exports["sky_ambulancejob"]:OpenSelfDiagnose()
if not success then
    print("Self-diagnose failed: " .. (reason or "unknown"))
end
This export can also be triggered via the /selfdiagnose chat command (configurable in Config.SelfDiagnose.command) or via the Self-diagnose radial menu action.

Insurance

OpenInsurance()

  • Purpose: Opens the insurance UI for the local player.
exports["sky_ambulancejob"]:OpenInsurance()

Stretcher

openStretcherEditor(payload)

  • Purpose: Opens the interactive stretcher positioning editor for vehicle attachment configuration. Spawns a preview vehicle with an attached stretcher that can be repositioned via keyboard controls.
  • Arguments:
    • payload (table):
      • model (string | number) — Vehicle model name or hash. Required.
      • name (string?) — Optional display name for the vehicle.
  • Returns: table with:
    • success (boolean) — true when the editor opened successfully.
    • error (string?) — Error message when success is false.
local result = exports["sky_ambulancejob"]:openStretcherEditor({
    model = "ambulance",
    name  = "Ambulance"
})

if not result.success then
    print("Error: " .. result.error)
end

Minigames

The ambulancejob minigames can be used standalone from any other resource. Each export opens the minigame UI and yields until the player completes or fails it.

StartMinigame(type, options?)

  • Purpose: Starts any minigame by type. This is the universal entry point for all standalone minigames.
  • Arguments:
    • type (string): The minigame to start — see table below.
    • options (table?): Optional configuration.
      • variant (string?): For bandage_wrap only — "arm", "leg", "head", or "torso" (default "arm").
      • messages (table?): Override any display text in the minigame UI. Keys match the short locale keys of each component (e.g. title, subtitle, hint, fail, success). Any key not provided falls back to the default locale string.
  • Returns:
    • boolean: true when the minigame started, false on error.
    • boolean | string: When started — true on success, false on fail. When not started — error reason ("invalid_type", "busy").
TypeDescription
"bandage_wrap"Trace a spiral path to wrap a wound. Accepts variant option.
"cpr"Full CPR — hit compression beats at rhythm, then deliver rescue breaths.
"cpr_compressions"Chest compressions only (no ventilation phase).
"cpr_ventilation"Rescue breaths only (trace the airflow wave).
"bullet_extraction"Drag a bullet upward through a canal without hitting the walls.
"saline_infusion"Regulate IV drip flow by adjusting a clamp to the target rate.
"blood_transfusion"Control blood flow rate within the target zone.
"bag_valve_mask"Trace an airflow wave to deliver breaths (3 breaths required).
local started, result = exports["sky_ambulancejob"]:StartMinigame("cpr")
if started and result then
    print("CPR successful!")
end

Message overrides

Every minigame component resolves its display text through short keys. Pass a messages table to override any of them:

local started, success = exports["sky_ambulancejob"]:StartMinigame("bullet_extraction", {
    messages = {
        title    = "Remove the splinter",
        subtitle = "Carefully pull it out without touching the walls.",
        fail     = "Wall contact!",
        success  = "Removed!",
    }
})

Keys that are not provided in the table fall back to the configured locale. Below is the full key reference for each minigame type.

bandage_wrap

KeyDefaultNote
title(per variant)Overrides the variant-specific title
titles.armApply arm gauze wrap
titles.legApply leg gauze wrap
titles.headApply head gauze wrap
titles.torsoStabilize torso gauze wrap
subtitleFollow the spiral path and stay close to the guide.
hintStart at the highlighted point and wrap upward in a spiral.
failToo far away - try again!

cpr / cpr_compressions

KeyDefaultNote
compressActionPress Space or click with the rhythm
missLabelMisses {count}/{max}Supports {count}, {max}
cycleLabelCycle {count}/{total}Supports {count}, {total}
phaseCompressions{count} compressionsSupports {count}
phaseVentilationDeliver {count} breathsOnly in full cpr mode
ventilationStageTitleRescue breathsOnly in full cpr mode
ventilationStageSubtitleTrace the mask alignment to deliver airflow.Only in full cpr mode
ventilationProgressBreaths {count}/{total}Only in full cpr mode

cpr_ventilation

KeyDefault
ventilationTitleDeliver rescue breaths
ventilationSubtitleTrace the airflow curve to deliver a breath.
ventilationHintStart at the highlighted marker and follow the wave.
ventilationFailBreath lost - reset and try again.
failTimeoutVentilation aborted - too slow.

bullet_extraction

KeyDefault
titleExtract the bullet
subtitleDrag the bullet straight up without touching the canal walls.
hintStay centered between the glowing rails.
progressExtraction progress
exitExit
failWall contact! Try again.
successBullet removed.
bulletAltDeformed bullet

saline_infusion

KeyDefaultNote
titleSaline infusion
subtitleRegulate the drip and keep the flow steady.
rateDrip rate
progressInfusion progress
stopAbort infusion
targetHintKeep between {low}–{high} drops/minSupports {low}, {high}
adjustAdjust the clamp into the highlighted zone.
successFlow is stable.
failOverFlow too high!
failUnderLine collapsed - reopen the clamp.
failTimeoutInfusion aborted - took too long.
progressHintKeep steady… {value}%Supports {value}

blood_transfusion

KeyDefaultNote
titleBlood transfusion setup
subtitleStabilise the transfusion flow.
rateFlow rate
progressInfusion progress
stopAbort transfusion
adjustAdjust the regulator into the highlighted zone.
stageCompleteFlow stabilised.
failOverFlow too strong! Slow down.
failUnderLine collapsed! Raise the flow.
failTimeoutTransfusion aborted - procedure took too long.
progressHintHold steady… {value}%Supports {value}

bag_valve_mask

KeyDefault
titleBag valve mask ventilation
subtitleTrace the airflow curve to deliver a breath.
hintStart at the highlighted marker and follow the wave.
progressBreaths {count}/{total}
successBreathBreath delivered
StartMinigame is yielding — it blocks the current thread until the player finishes or cancels the minigame. Call it inside a CreateThread or Citizen.CreateThread to avoid blocking your main thread.

IsMinigameActive()

  • Purpose: Checks if a standalone minigame is currently running.
  • Returns: boolean
if exports["sky_ambulancejob"]:IsMinigameActive() then
    print("A minigame is in progress")
end

GetActiveMinigame()

  • Purpose: Returns the type of the currently active standalone minigame.
  • Returns: string | nil
local active = exports["sky_ambulancejob"]:GetActiveMinigame()

CancelMinigame()

  • Purpose: Cancels the currently running standalone minigame. The minigame counts as failed.
exports["sky_ambulancejob"]:CancelMinigame()

GetAvailableMinigames()

  • Purpose: Returns a table of all minigame types with their enabled/disabled state from Config.Minigames.enabled.
  • Returns: table<string, boolean>
local available = exports["sky_ambulancejob"]:GetAvailableMinigames()
for name, enabled in pairs(available) do
    print(name .. ": " .. tostring(enabled))
end

Example: Using minigames in another resource

-- In your custom resource (client-side)
CreateThread(function()
    -- Example: require a CPR minigame before reviving
    local started, success = exports["sky_ambulancejob"]:StartMinigame("cpr")
    if started and success then
        TriggerServerEvent("myresource:revivePlayer")
    else
        TriggerEvent("chat:addMessage", {
            args = { "CPR failed — the patient could not be revived." }
        })
    end
end)
-- Example: bandage wrap as a skill check with custom text
RegisterCommand("applybandage", function()
    CreateThread(function()
        local started, success = exports["sky_ambulancejob"]:StartMinigame("bandage_wrap", {
            variant = "arm",
            messages = {
                title = "Apply field dressing",
                subtitle = "Wrap the wound carefully.",
            }
        })
        if started and success then
            print("Bandage applied successfully")
        end
    end)
end)

Support

Need help? Our support team is always ready to assist

Join Discord