TIMMYG Studios

API Reference

Complete API reference for Tommy's Radio exports, functions, and events.

Server ExportsClient ExportsEvents

Server Exports

Channel Information

getSpeakersInChannel(frequency)

Get all users connected to transmit on a specific channel.

Parameters:

  • frequency (string/number) - Channel frequency (e.g., "154.755")

Returns: table - Array of server IDs actively speaking on the channel

Example Usage
local speakers = exports['radio']:getSpeakersInChannel("154.755")
for _, serverId in ipairs(speakers) do
    local name = exports['radio']:getPlayerName(serverId)
    print(name .. " can transmit on dispatch")
end

getListenersInChannel(frequency)

Get all users listening to a channel without transmit capability.

Parameters:

  • frequency (string/number) - Channel frequency

Returns: table - Array of server IDs listening to the channel

Example Usage
local listeners = exports['radio']:getListenersInChannel("154.755")
print("Channel has " .. #listeners .. " listeners")

getAllUsersInChannel(frequency)

Get all users on a channel regardless of role (speakers + listeners combined).

Parameters:

  • frequency (string/number) - Channel frequency

Returns: table - Array of server IDs on the channel

Example Usage
local allUsers = exports['radio']:getAllUsersInChannel("154.755")
print("Total users on channel: " .. #allUsers)

getActiveTalkersInChannel(frequency)

Get users actively talking right now on the channel (PTT pressed).

Parameters:

  • frequency (string/number) - Channel frequency

Returns: table - Array of server IDs currently transmitting

Example Usage
local talkers = exports['radio']:getActiveTalkersInChannel("154.755")
if #talkers > 0 then
    print("Someone is transmitting on dispatch!")
end

getActiveChannels()

Get list of all channels with active users.

Returns: table - Array of active channel frequencies

Example Usage
local activeChannels = exports['radio']:getActiveChannels()
for _, frequency in ipairs(activeChannels) do
    print("Channel " .. frequency .. " is active")
end

getChannelInfo(channel)

Get detailed information about a specific channel.

Parameters:

  • channel (string/number) - Channel frequency

Returns: table - Channel object with speakers, listeners, activeTalkers arrays, or nil

Example Usage
local channelInfo = exports['radio']:getChannelInfo("154.755")
if channelInfo then
    print("Speakers: " .. #channelInfo.speakers)
    print("Listeners: " .. #channelInfo.listeners)
    print("Active Talkers: " .. #channelInfo.activeTalkers)
end

getAllChannels()

Get complete list of channels from config with zones, names, types, etc.

Returns: table - Array of all configured channels with full details

Example Usage
local channels = exports['radio']:getAllChannels()
for _, channel in ipairs(channels) do
    print(channel.name .. " - " .. channel.frequency .. " (" .. channel.zone .. ")")
end

Alert & Signal Management

getChannelAlert(frequency)

Get active alert on a channel (e.g., "Signal 100").

Parameters:

  • frequency (string/number) - Channel frequency

Returns: table - Alert object {name, color, tone, isPersistent} or nil if no alert

Example Usage
local alert = exports['radio']:getChannelAlert("154.755")
if alert then
    print("Alert active: " .. alert.name)
end

setChannelSignal(frequency, enabled)

Activate or clear an alert on a channel.

Parameters:

  • frequency (string/number) - Channel frequency
  • enabled (boolean) - Alert state

Returns: boolean - true on success

Example Usage
-- Activate Signal 100 on dispatch
exports['radio']:setChannelSignal("154.755", true)

-- Clear signal after 60 seconds
Wait(60000)
exports['radio']:setChannelSignal("154.755", false)

getChannelPanic(frequency)

Get all users with panic activated on a channel.

Parameters:

  • frequency (string/number) - Channel frequency

Returns: table - Table of server IDs with active panic buttons

Example Usage
local panicUsers = exports['radio']:getChannelPanic("154.755")
for serverId, _ in pairs(panicUsers) do
    print("User " .. serverId .. " has panic active!")
end

setChannelPanic(frequency, serverId, enabled)

Set or clear panic button for a specific user on a channel.

Parameters:

  • frequency (string/number) - Channel frequency
  • serverId (number) - Player's server ID
  • enabled (boolean) - Panic state

Returns: boolean - true on success

Example Usage
-- Activate panic for officer
exports['radio']:setChannelPanic("154.755", 1, true)

-- Clear panic
exports['radio']:setChannelPanic("154.755", 1, false)

getUserPanicState(serverId, frequency)

Check if a specific user has panic active on a channel.

Parameters:

  • serverId (number) - Player's server ID
  • frequency (string/number) - Channel frequency

Returns: boolean - Panic state

Example Usage
if exports['radio']:getUserPanicState(1, "154.755") then
    print("Officer has emergency activated!")
end

User Management

setUserChannel(serverId, frequency)

Move a user to a specific channel (handles trunked channels automatically).

Parameters:

  • serverId (number) - Player's server ID
  • frequency (string/number) - Target channel frequency

Returns: boolean - true on success

Example Usage
-- Move officer to tactical channel
local success = exports['radio']:setUserChannel(1, "155.475")
if success then
    print("Officer moved to tactical channel")
end

disconnectUser(serverId)

Disconnect a user from the radio system.

Parameters:

  • serverId (number) - Player's server ID

Returns: boolean - true on success

Example Usage
-- Remove user from radio (e.g., when going off-duty)
exports['radio']:disconnectUser(1)

isUserTalking(serverId, frequency)

Check if a specific user is actively transmitting on a channel.

Parameters:

  • serverId (number) - Player's server ID
  • frequency (string/number) - Channel frequency

Returns: boolean - Transmit state

Example Usage
if exports['radio']:isUserTalking(1, "154.755") then
    print("User 1 is transmitting on dispatch")
end

User Information

getPlayerName(serverId)

Get the display name of a player.

Parameters:

  • serverId (number) - Player's server ID

Returns: string - Player name

Example Usage
local name = exports['radio']:getPlayerName(1)
print("Player name: " .. name)

getUserNacId(serverId)

Get a user's Network Access Code ID.

Parameters:

  • serverId (number) - Player's server ID

Returns: string - NAC ID or nil

Example Usage
local nacId = exports['radio']:getUserNacId(1)
if nacId then
    print("NAC ID: " .. nacId)
end

getUserInfo(serverId)

Get both name and NAC ID for a user.

Parameters:

  • serverId (number) - Player's server ID

Returns: table - User info {name, nacId}

Example Usage
local userInfo = exports['radio']:getUserInfo(1)
print(userInfo.name .. " - NAC: " .. (userInfo.nacId or "N/A"))

hasRadioAccess(serverId)

Check if a user has radio system access.

Parameters:

  • serverId (number) - Player's server ID

Returns: boolean - Access state

Example Usage
if exports['radio']:hasRadioAccess(source) then
    -- Grant radio permissions
end

Audio Control

playToneOnChannel(frequency, tone)

Play a tone to all users on a specific channel.

Parameters:

  • frequency (string/number) - Channel frequency
  • tone (string) - Tone name (e.g., "beep", "chirp")
Example Usage
-- Play tone to entire dispatch channel
exports['radio']:playToneOnChannel("154.755", "alert")

playToneOnSource(serverId, tone)

Play a tone to a specific user only.

Parameters:

  • serverId (number) - Player's server ID
  • tone (string) - Tone name
Example Usage
-- Play confirmation tone to specific officer
exports['radio']:playToneOnSource(1, "beep")

Client Exports

Radio Control

setCurrentChannel(channel)

Set your main speaking channel.

Parameters:

  • channel (string/number) - Channel frequency
Example Usage
-- Switch to dispatch channel
exports['radio']:setCurrentChannel("154.755")

getCurrentFrequency()

Get your current channel frequency.

Returns: string/number - Current frequency, or -1 if not connected

Example Usage
local freq = exports['radio']:getCurrentFrequency()
if freq ~= -1 then
    print("Current frequency: " .. freq)
end

getCurrentChannel()

Get complete information about your current channel.

Returns: table - Channel object with full details

Example Usage
local channel = exports['radio']:getCurrentChannel()
if channel then
    print("On: " .. channel.name .. " (" .. channel.frequency .. ")")
end

openRadio()

Open the radio interface UI.

Example Usage
exports['radio']:openRadio()

closeRadio()

Close the radio interface UI.

Example Usage
exports['radio']:closeRadio()

Listening Channels

addListeningChannel(channel)

Add a channel to your listening list (scan).

Parameters:

  • channel (string/number) - Channel frequency
Example Usage
-- Add tactical channel to scan
exports['radio']:addListeningChannel("155.475")

removeListeningChannel(channel)

Remove a channel from your listening list.

Parameters:

  • channel (string/number) - Channel frequency
Example Usage
exports['radio']:removeListeningChannel("155.475")

getListeningChannels()

Get all channels you're currently scanning.

Returns: table - Array of channel frequencies

Example Usage
local listening = exports['radio']:getListeningChannels()
print("Scanning " .. #listening .. " channels")

Transmission Control

startTransmitting()

Start PTT transmission (same as pressing PTT key).

Example Usage
exports['radio']:startTransmitting()

stopTransmitting()

Stop PTT transmission (same as releasing PTT key).

Example Usage
exports['radio']:stopTransmitting()

isTransmitting()

Check if you're currently transmitting.

Returns: boolean - Transmit state

Example Usage
if exports['radio']:isTransmitting() then
    print("You are transmitting")
end

getActiveTalker()

Get information about who's currently talking on your frequency.

Returns: table - Talker info {serverId, name, frequency} or nil

Example Usage
local talker = exports['radio']:getActiveTalker()
if talker then
    print(talker.name .. " is talking on " .. talker.frequency)
end

setTalking(talking)

Set talking state for UI feedback.

Parameters:

  • talking (boolean) - Talking state
Example Usage
exports['radio']:setTalking(true)

Radio State

isConnected()

Check if connected to a channel.

Returns: boolean - Connection state

Example Usage
if exports['radio']:isConnected() then
    print("Radio connected")
end

isPowerOn()

Check if radio is powered on.

Returns: boolean - Power state

Example Usage
if exports['radio']:isPowerOn() then
    print("Radio is on")
end

isRadioOpen()

Check if radio UI is currently open.

Returns: boolean - UI state

Example Usage
if exports['radio']:isRadioOpen() then
    print("Radio UI is displayed")
end

Audio & Volume

setVolume(volume)

Set radio voice volume.

Parameters:

  • volume (number) - Volume level 0.0 to 1.0
Example Usage
exports['radio']:setVolume(0.75)

getVolume()

Get current radio voice volume.

Returns: number - Volume level 0.0 to 1.0

Example Usage
local volume = exports['radio']:getVolume()
print("Voice volume: " .. (volume * 100) .. "%")

setToneVolume(volume)

Set tone/SFX volume.

Parameters:

  • volume (number) - Volume level 0.0 to 1.0
Example Usage
exports['radio']:setToneVolume(0.35)

getToneVolume()

Get current tone/SFX volume.

Returns: number - Volume level 0.0 to 1.0

Example Usage
local toneVol = exports['radio']:getToneVolume()
print("Tone volume: " .. (toneVol * 100) .. "%")

set3DVolume(volume)

Set 3D audio volume.

Parameters:

  • volume (number) - Volume level 0.0 to 1.0
Example Usage
exports['radio']:set3DVolume(0.5)

get3DVolume()

Get current 3D audio volume.

Returns: number - Volume level 0.0 to 1.0

Example Usage
local vol3D = exports['radio']:get3DVolume()
print("3D audio volume: " .. (vol3D * 100) .. "%")

playTone(tone)

Play a tone locally.

Parameters:

  • tone (string) - Tone name (e.g., "beep", "chirp")
Example Usage
exports['radio']:playTone("beep")

Appearance & Layout

setRadioLayout(layout)

Change radio style/model.

Parameters:

  • layout (string) - Radio model name (e.g., "ATX-8000")
Example Usage
exports['radio']:setRadioLayout("ATX-8000")

getRadioLayout()

Get current radio layout.

Returns: string - Radio model name

Example Usage
local layout = exports['radio']:getRadioLayout()
print("Radio model: " .. layout)

setRadioTheme(theme)

Change radio UI theme.

Parameters:

  • theme (string) - Theme name (e.g., "Dark", "Auto")
Example Usage
exports['radio']:setRadioTheme("Dark")

getRadioTheme()

Get current radio theme.

Returns: string - Theme name

Example Usage
local theme = exports['radio']:getRadioTheme()
print("Theme: " .. theme)

setAnimationId(animId)

Set radio animation.

Parameters:

  • animId (number) - Animation index
Example Usage
exports['radio']:setAnimationId(2)

getAnimationId()

Get current animation ID.

Returns: number - Animation index

Example Usage
local animId = exports['radio']:getAnimationId()
print("Animation ID: " .. animId)

Settings

setEarbudsEnabled(enabled)

Enable/disable earbuds (disables 3D audio).

Parameters:

  • enabled (boolean) - Earbuds state
Example Usage
exports['radio']:setEarbudsEnabled(true)

getEarbudsEnabled()

Get earbuds state.

Returns: boolean - Earbuds enabled

Example Usage
if exports['radio']:getEarbudsEnabled() then
    print("Earbuds mode active")
end

setGPSEnabled(enabled)

Enable/disable GPS tracking.

Parameters:

  • enabled (boolean) - GPS state
Example Usage
exports['radio']:setGPSEnabled(true)

getGPSEnabled()

Get GPS state.

Returns: boolean - GPS enabled

Example Usage
if exports['radio']:getGPSEnabled() then
    print("GPS tracking enabled")
end

Alerts & Panic

triggerAlertOnChannel(frequency, enabled)

Trigger or clear an alert on a channel (sends to server).

Parameters:

  • frequency (string/number) - Channel frequency
  • enabled (boolean) - Alert state
Example Usage
-- Trigger Signal 100
exports['radio']:triggerAlertOnChannel("154.755", true)

panicButton(frequency, enabled)

Activate or clear panic button on a channel.

Parameters:

  • frequency (string/number) - Channel frequency
  • enabled (boolean) - Panic state
Example Usage
-- Activate panic
exports['radio']:panicButton("154.755", true)

User Information

getCurrentName()

Get your own player name.

Returns: string - Your player name

Example Usage
local myName = exports['radio']:getCurrentName()
print("You are: " .. myName)

getCurrentNacId()

Get your own NAC ID.

Returns: string - Your NAC ID or nil

Example Usage
local myNac = exports['radio']:getCurrentNacId()
if myNac then
    print("Your NAC: " .. myNac)
end

getZone()

Get your current zone name.

Returns: string - Zone name

Example Usage
local zone = exports['radio']:getZone()
print("Current zone: " .. zone)

System

getBatteryLevel()

Get radio battery level percentage.

Returns: number - Battery level 0-100

Example Usage
local battery = exports['radio']:getBatteryLevel()
print("Battery: " .. battery .. "%")

getSignalStrength()

Get current signal strength.

Returns: number/boolean - Signal strength value

Example Usage
local signal = exports['radio']:getSignalStrength()
print("Signal: " .. signal)

getConnectionDiagnostics()

Get detailed connection diagnostics for troubleshooting.

Returns: table - Diagnostic information

Example Usage
local diagnostics = exports['radio']:getConnectionDiagnostics()
for key, value in pairs(diagnostics) do
    print(key .. ": " .. tostring(value))
end

Usage Examples

Basic Channel Management

Server-Side Channel Control
-- Get all users on dispatch
local speakers = exports['radio']:getSpeakersInChannel("154.755")
local listeners = exports['radio']:getListenersInChannel("154.755")

print("Dispatch channel has:")
print("- " .. #speakers .. " units with transmit")
print("- " .. #listeners .. " supervisors listening")

-- Move officer to tactical
exports['radio']:setUserChannel(1, "155.475")

-- Check who's talking
local talkers = exports['radio']:getActiveTalkersInChannel("154.755")
if #talkers > 0 then
    for _, serverId in ipairs(talkers) do
        local name = exports['radio']:getPlayerName(serverId)
        print(name .. " is transmitting")
    end
end

Emergency System Integration

Panic Button Handler
-- Server-side emergency response
RegisterNetEvent('radio:handlePanic')
AddEventHandler('radio:handlePanic', function(frequency)
    local serverId = source
    local name = exports['radio']:getPlayerName(serverId)
    local nacId = exports['radio']:getUserNacId(serverId)

    -- Activate panic
    exports['radio']:setChannelPanic(frequency, serverId, true)

    -- Trigger Signal 100 on dispatch
    if frequency == "154.755" then
        exports['radio']:setChannelSignal(frequency, true)
        print("EMERGENCY: " .. name .. " (" .. nacId .. ") activated panic!")

        -- Play alert tone to all dispatch users
        exports['radio']:playToneOnChannel(frequency, "emergency")

        -- Auto-clear after 2 minutes
        SetTimeout(120000, function()
            exports['radio']:setChannelSignal(frequency, false)
            exports['radio']:setChannelPanic(frequency, serverId, false)
        end)
    end
end)

Radio State Monitoring

Client-Side State Checking
-- Check radio status before transmitting
Citizen.CreateThread(function()
    while true do
        Wait(5000)

        if exports['radio']:isConnected() and exports['radio']:isPowerOn() then
            local freq = exports['radio']:getCurrentFrequency()
            local channel = exports['radio']:getCurrentChannel()

            if freq ~= -1 then
                print("Connected to: " .. channel.name)

                -- Check who's talking
                local talker = exports['radio']:getActiveTalker()
                if talker then
                    print(talker.name .. " is speaking")
                end

                -- Monitor battery
                local battery = exports['radio']:getBatteryLevel()
                if battery < 20 then
                    print("WARNING: Low battery (" .. battery .. "%)")
                end
            end
        else
            print("Radio offline")
        end
    end
end)

Multi-Channel Scanning

Client-Side Channel Scanning
-- Setup multi-channel monitoring for supervisors
local function setupSupervisorRadio()
    -- Set primary channel to dispatch
    exports['radio']:setCurrentChannel("154.755")

    -- Add listening channels for all divisions
    exports['radio']:addListeningChannel("155.475") -- Tactical 1
    exports['radio']:addListeningChannel("155.490") -- Tactical 2
    exports['radio']:addListeningChannel("154.920") -- Fire/EMS

    -- Configure volumes
    exports['radio']:setVolume(0.8)
    exports['radio']:setToneVolume(0.3)
    exports['radio']:set3DVolume(0.5)

    print("Supervisor radio configured")
    local listening = exports['radio']:getListeningChannels()
    print("Monitoring " .. #listening .. " channels")
end

Advanced Channel Info

Server-Side Monitoring Dashboard
-- Get comprehensive channel status
local function getChannelStatus()
    local activeChannels = exports['radio']:getActiveChannels()

    for _, frequency in ipairs(activeChannels) do
        local info = exports['radio']:getChannelInfo(frequency)
        local alert = exports['radio']:getChannelAlert(frequency)
        local panicUsers = exports['radio']:getChannelPanic(frequency)

        print("=== Channel " .. frequency .. " ===")
        print("Speakers: " .. #info.speakers)
        print("Listeners: " .. #info.listeners)
        print("Active Talkers: " .. #info.activeTalkers)

        if alert then
            print("ALERT: " .. alert.name)
        end

        local panicCount = 0
        for _ in pairs(panicUsers) do panicCount = panicCount + 1 end
        if panicCount > 0 then
            print("PANIC: " .. panicCount .. " units")
        end
    end
end

Error Handling

Important Notes

  • Always check return values from export functions
  • Frequencies can be passed as strings ("154.755") or numbers (154.755)
  • Volume values are normalized to 0.0-1.0 range (not 0-100)
  • Server exports return nil or false on failure
  • Client exports return -1 or nil when radio is disconnected
  • NAC ID checks should handle nil returns gracefully