Configuration
config.lua
public/framework.lua, public/inventory.lua, and public/dead.lua are the only files meant to be edited for a custom integration — see the auto-compatible "downed" detection note under Common Issues if you plan to swap Config.DeadDetection for your own check.
config.luaLua
Config = {}
-- =====================================================================
-- GENERAL
-- =====================================================================
-- Chat command that opens the radio menu.
Config.Command = 'radio'
-- Default key to open the menu (the player can rebind it in
-- Settings > Key Bindings). Leave as '' to disable it.
Config.OpenKey = ''
-- Lets you WALK while the radio menu is open.
-- The mouse still works to click buttons. As soon as you focus a text
-- field (frequency / sound search) movement locks so you can type, and
-- unlocks again when you leave the field.
-- true = you can move around with the menu open.
-- false = the menu blocks movement (classic behaviour).
Config.CanWalkWhileUsing = true
-- UI and notifications language. Files live in locales/<code>.lua
Config.Locale = 'es'
-- =====================================================================
-- COLOR / THEME
-- A single color and the WHOLE interface (borders, backgrounds, glow,
-- slider, scrollbar, overlay...) is calculated from it. Accepts a 3 or
-- 6 digit hex, with or without '#'.
-- =====================================================================
Config.Color = '#0098FF'
-- Allowed frequency range.
Config.MinFrequency = 1
Config.MaxFrequency = 999999
-- Decimal places allowed in the frequency (e.g. 1.1, 25.75). FiveM/pma-voice
-- support this. 0 = integers only. 1 = one decimal. 2 = two decimals...
Config.FrequencyDecimals = 1
-- Initial radio volume (0 - 100).
Config.DefaultVolume = 50
-- Text shown instead of the real name when anonymous mode is on.
-- A short id is appended to tell players apart.
Config.AnonymousPrefix = 'Anonimo'
-- =====================================================================
-- DEATH / INCAPACITATED
-- =====================================================================
-- true = dying automatically disconnects you from the frequency and
-- closes the menu if you have it open.
-- false = you stay connected even if you die.
Config.DisconnectOnDead = true
-- true = you can open the menu and join a frequency while downed.
-- false = the radio can't be used while downed/incapacitated.
Config.CanUseDead = false
-- Turns the "downed / incapacitated" detection on or off. All of its
-- logic lives in public/dead.lua (same pattern as framework.lua and
-- inventory.lua) so it's easy to replace with your own integration.
-- true = use the automatic detection (natives + statebags + framework).
-- false = Dead.IsDead() always returns false (or put your own check here).
Config.DeadDetection = true
-- AUTO-COMPATIBLE "downed / incapacitated" detection. Besides the game's
-- natives (IsEntityDead / IsPlayerDead), these LocalPlayer.state statebags
-- are checked (true = downed). Covers wasabi_ambulance ('dead' / 'isDead' /
-- 'laststand'), qb-ambulancejob ('isdead' / 'inlaststand') and
-- esx_ambulancejob ('dead' / 'isDead') out of the box. Add or remove keys
-- to match your server.
Config.DeadStateBags = { 'dead', 'isDead', 'isdead', 'laststand', 'inlaststand' }
-- If you have wasabi_ambulance, its export
-- exports.wasabi_ambulance:isPlayerDead() is also checked automatically.
-- =====================================================================
-- REQUIRED ITEM
-- =====================================================================
-- true = an item is required to open the menu and join a frequency
-- (and you get kicked out if you lose/drop it).
-- false = the radio works without any item.
Config.RequireItem = true
-- Item name in your inventory.
Config.ItemName = 'radio'
-- How often (ms) to check that you still have the item while on a
-- frequency. Only used if Config.RequireItem = true.
Config.ItemCheckInterval = 10000
-- Forces a specific inventory/framework instead of auto-detecting.
-- '' or 'auto' = detect only (recommended).
-- Inventory: 'ox_inventory' | 'qb-inventory' | 'qs-inventory' | 'origen_inventory'
-- Framework : 'qbox' | 'qbcore' | 'esx'
Config.ForceInventory = 'auto'
Config.ForceFramework = 'auto'
-- =====================================================================
-- RADIO TALKING ANIMATIONS
-- - dict/anim : applied to pma-voice (exports['pma-voice']:setRadioTalkAnim).
-- - prop : model attached to the hand while transmitting (optional).
-- - propOptions: how the prop is attached to the ped's bone.
-- offset/rot = vector3, bone = bone index.
-- =====================================================================
Config.Animations = {
{
id = 'hombro',
label = 'Al hombro',
desc = 'Lapel mic: hand to the shoulder.',
dict = 'random@arrests',
anim = 'generic_radio_chatter',
prop = 'prop_cs_hand_radio',
propOptions = {
offset = vector3(0.055, 0.055, 0.035),
rot = vector3(-103.000, 0.000, 0.000),
bone = 60309,
},
},
{
id = 'boca',
label = 'Boca',
desc = 'Holds the radio up to the mouth.',
dict = 'anim@male@holding_radio',
anim = 'holding_radio_clip',
prop = 'prop_cs_hand_radio',
propOptions = {
offset = vector3(0.0750, 0.0230, -0.0230),
rot = vector3(-90.0000, 0.0, -59.9999),
bone = 28422,
},
},
{
id = 'oreja',
label = 'En la oreja',
desc = 'Brings the radio up to the ear.',
dict = 'cellphone@str',
anim = 'cellphone_call_listen_a',
prop = 'prop_cs_hand_radio',
propOptions = {
offset = vector3(-0.01, -0.01, 0.02),
rot = vector3(0.0, 0.0, 0.0),
bone = 28422,
},
},
}
-- Default animation selected (id from the list above).
Config.DefaultAnimation = 'boca'
-- =====================================================================
-- "RADIO IN HAND" ANIMATION (while the menu is open)
-- INDEPENDENT from the talking animations above: it only plays while
-- the menu is open and makes the ped hold the radio and look at it,
-- phone-style. Starting to transmit hands off to the pma-voice
-- animation, and releasing PTT brings this one back.
-- =====================================================================
Config.HoldAnimation = {
-- true = enable / false = disable this animation.
enabled = true,
dict = 'cellphone@',
enter = 'cellphone_text_in', -- entry (played once). '' = no entry.
idle = 'cellphone_text_read_base', -- loop while the menu is open.
-- Prop attached to the hand (optional; '' to attach none).
prop = 'prop_cs_hand_radio',
propBone = 28422,
propOffset = vector3(0.0, 0.0, 0.0),
propRot = vector3(0.0, 0.0, 0.0),
}
-- =====================================================================
-- SOUNDS
-- Files live in the biyei_radio/sound/ folder (NOT inside web/) so
-- rebuilding the UI never deletes them.
--
-- - start : played when you START transmitting / receiving.
-- - finish : (optional) played when you RELEASE / end transmitting.
--
-- The player picks one of these in the radio menu.
-- =====================================================================
Config.Sounds = {
{ id = 'beep', label = 'Beep', start = 'beep.mp3' },
{ id = 'bipbip', label = 'Bip-bip', start = 'bipbip.mp3' },
{ id = 'chiclkin', label = 'Click', start = 'chiclkin.mp3' },
{ id = 'connect', label = 'Conexion', start = 'connect.mp3' },
{ id = 'error', label = 'Error', start = 'error.mp3' },
{ id = 'militar', label = 'Militar', start = 'militar.mp3' },
{ id = 'notification', label = 'Notificacion', start = 'notification.mp3' },
{ id = 'police', label = 'Policia', start = 'police.mp3' },
{ id = 'pop', label = 'Pop', start = 'pop.mp3' },
{ id = 'tin', label = 'Tin', start = 'tin.mp3' },
{ id = 'turconorolas', label = 'Motorola', start = 'turconorolas.mp3' },
}
-- Default sound selected (id from the list above, or '' for none).
Config.DefaultSound = 'beep'
--- Rounds a frequency to Config.FrequencyDecimals and validates it against
--- the allowed range. Returns a number or nil. (shared client/server)
function Config.NormalizeFrequency(v)
v = tonumber(v)
if not v then return nil end
local p = math.max(0, math.floor(Config.FrequencyDecimals or 0))
local m = 10 ^ p
v = math.floor(v * m + 0.5) / m
if v < Config.MinFrequency or v > Config.MaxFrequency then return nil end
return v
end
-- =====================================================================
-- Character name resolution (framework) and item checking (inventory)
-- now live in the public/ folder so each server can adapt them without
-- touching the rest of the resource:
-- public/framework.lua -> auto-detect QBox / QBCore / ESX
-- public/inventory.lua -> auto-detect ox / qb / qs / origen inventory
-- public/dead.lua -> auto-detect "downed / incapacitated"
-- =====================================================================