Skip to content

Retro Hidden Mic

All configuration is done in two open files: config/config.lua and config/webhooks.lua. This page covers both in detail.


config/config.lua
Config.Debug = false
Config.Locale = 'en' -- 'en', 'pl', 'ar', 'cn', 'de', 'es', 'fr', 'hu', 'it', 'ja', 'pt', 'sv', 'zh-tw'
Config.Framework = 'ESX' -- 'ESX', 'QBCore', 'Qbox'
Config.NotificationType = 'esx' -- 'ox_lib', 'esx', 'okokNotify', 'ps-ui', 'nox_notify', 'lation_ui', 'QBCore', 'Qbox'
Config.ProgressBar = 'ox-bar' -- 'ox-circle', 'ox-bar', 'esx', 'lation_ui', 'qb'
-- Recommended: 'auto' or 'default' uses this script's built-in TextUI
Config.TextUI = 'auto' -- 'auto', 'default', 'jg-textui', 'okok', 'ps-ui', 'lation_ui', 'ox_lib', 'qbcore', 'esx'
Config.PlacementUIPosition = 'bottom-right' -- 'center-right' or 'bottom-right'
Config.TargetType = 'ox_target' -- 'ox_target' or 'qb-target'
-- Distance for target/textui interactions
Config.DistanceInteract = 2.0

Each action plays an animation for a set duration (the progress bar length, in ms). Adjust the dictionary, clip, or duration per action.

config/config.lua:Animations
Config.Animations = {
BugFloor = { dict = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', anim = 'plant_floor', duration = 2000 },
BugWall = { dict = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', anim = 'plant_vertical', duration = 2000 },
BugPlayer = { dict = 'anim@heists@ornate_bank@hack', anim = 'hack_loop', duration = 2000 },
BugVehicle = { dict = 'anim@heists@ornate_bank@hack', anim = 'hack_loop', duration = 2000 },
Jammer = { dict = 'anim@heists@ornate_bank@hack', anim = 'hack_loop', duration = 2000 },
Amplifier = { dict = 'anim@heists@ornate_bank@hack', anim = 'hack_loop', duration = 2000 },
Remove = { dict = 'anim@heists@ornate_bank@hack', anim = 'hack_loop', duration = 2000 },
}

Defines the three bug item names, the visible prop, listening ranges, battery behaviour, and limits.

config/config.lua:Wiretapping
Config.BugItem = 'room_bug' -- Item name for a standard (room) bug
Config.BugPlayerItem = 'player_bug' -- Item name for a player/wearable bug
Config.BugVehicleItem = 'vehicle_bug' -- Item name for a vehicle bug
Config.BugSetup = {
SpawnProp = true, -- Spawn a visible prop after planting a room bug
PropModel = 'prop_ts_wiretapping', -- Prop model for the room bug
}
-- Listening ranges (meters): players within range of the bug are heard
Config.BugListenRange = 15.0 -- Room bug
Config.BugPlayerListenRange = 5.0 -- Player bug
Config.BugVehicleListenRange = 5.0 -- Vehicle bug
-- Battery life in seconds (60*60 = 1 hour)
Config.BatteryLife = {
Surface = 3600,
Player = 3600,
Vehicle = 3600,
}
Config.RemoveBugOnBatteryEmpty = false -- Remove the bug automatically when the battery hits 0
Config.MaxBugsPerPlayer = 50 -- Maximum active bugs per player
Config.ProximityCheckInterval = 2000 -- Interval for checking players near a bug (ms)
Config.BaseCallChannel = 9000 -- Base pma-voice channel for bugs (avoid collisions)
Config.Player_Control = true -- Disable player controls while planting (recommended)
Config.ShowNearbyPlayers = false -- Show the list of nearby players in the menu

The scanner is a weapon that reveals nearby planted bugs and lets the holder remove them.

config/config.lua:Scaner
Config.ScanerWeapon = `WEAPON_DIGISCANNER` -- Scanner weapon used to detect bugs
Config.KeyRemoveBug = {
KeyId = 182, -- Control ID used to remove a detected bug
KeyLabel = 'L', -- Label shown in the prompt
}
-- Color-coded directional indication for moving bugs (vehicles/players)
Config.EnableDirectionalScannerForDynamicBugs = false

Controls how far a signal reaches and where the wiretap menu can be opened. Command Centers are the job-gated points that open the panel; the antenna coordinate is where range is measured from.

config/config.lua:Signal System
-- Distance (m) at which the signal fades to 0% (and no sound) by default
Config.DefaultMaxSignalDistance = 600.0
Config.CommandCenters = {
{
name = "LSPD Police Station",
targetCoords = vector4(440.0, -980.0, 30.6, 187.4622), -- ox_target point
targetSize = vector3(1.0, 1.0, 2.0),
targetDrawSprite = true,
jobs = {
['police'] = 0 -- job = minimum grade (0 = everyone in police)
},
antennaCoords = vector3(425.0, -980.0, 45.0), -- Range is measured from here
maxSignalDistance = 3800.0, -- Custom range (omit to use DefaultMaxSignalDistance)
showOnMap = true, -- Show this center on the NUI map
mapIcon = '<i class="fa-solid fa-building-shield"></i>',
mapSize = 25, -- Icon size (px)
mapColor = '#4169e1' -- Icon color
},
}
-- NUI map icons (FontAwesome HTML, or '' for a small circle)
Config.MapIcons = {
amplifier = '<i class="fa-light fa-tower-broadcast"></i>',
bug_room = '',
bug_player = '<i class="fa-solid fa-user"></i>',
bug_vehicle = '<i class="fa-solid fa-car"></i>'
}
-- Signal thresholds (%): below each, the NUI hides the matching element
Config.SignalHideMapThreshold = 20 -- Hide bug from the map
Config.SignalHidePlayersThreshold = 15 -- Hide player count/list
Config.SignalHideWaveformThreshold = 5 -- Hide the speaking waveform

Signal strength drops with speed and obstruction. These globals tune those penalties.

config/config.lua:Signal Status
-- Speed (km/h) at which interference begins (player & vehicle bugs)
Config.SpeedPenaltyThreshold = 50.0
-- Signal drop (%) per 1 km/h above the threshold
Config.SpeedPenaltyMultiplier = 0.5
-- Penalty for being under a roof / in a tunnel / under an overpass
Config.EnableRoofPenalty = true
Config.RoofSignalPenalty = 25 -- Signal drop (%) when obstructed

A deployable device that cuts bug signals within its radius.

config/config.lua:Jammer
Config.JammerSetup = {
Item = 'bug_jammer',
SpawnProp = true,
PropModel = 'prop_ts_jammer', -- Prop model for the jammer
Range = 40.0, -- Operational radius (m)
Penalty = 100 -- Signal cut (%) for bugs in range (100 = no signal)
}

Extends signal range. Players can deploy amplifiers from an item, and you can also define static relays that spawn on resource start.

config/config.lua:Amplifier
Config.AmplifierSetup = {
Item = 'bug_signal_amplifier',
SpawnProp = true,
PropModel = 'prop_ts_amplifier', -- Prop model for the amplifier
Boost = 400.0 -- Extends signal range by this many meters
}
-- Static amplifiers spawned automatically when the script starts
Config.StaticAmplifiers = {
{
name = "Main Relay (Mount Chiliad)",
coords = vector3(765.0787, 1283.8098, 360.2965),
boost = 4000.0,
spawnProp = true,
alwaysShowPulse = false
},
}

All logging is configured in config/webhooks.lua. Choose a backend and provide its credentials.

config/webhooks.lua
Config.Webhooks = {
Enabled = true,
LogSystem = 'discord', -- 'discord', 'ox', 'datadog', 'fivemanage'
-- Discord
DefaultURL = "", -- Fallback webhook used when a specific URL is empty
URLs = {
Placing_wiretapping_room = "",
Placing_wiretapping_player = "",
Placing_wiretapping_vehicle = "",
Jammer = "",
Amplifier = "",
Notes = "",
Name_change = "",
Removal = "",
},
Colors = {
Placing_wiretapping_room = 12745742,
Placing_wiretapping_player = 12745742,
Placing_wiretapping_vehicle = 12745742,
Jammer = 10038562,
Amplifier = 2067276,
Notes = 15105570,
Name_change = 15105570,
Removal = 15548997,
},
-- Datadog (only if LogSystem = 'datadog')
DatadogApiKey = "",
DatadogSite = "datadoghq.eu",
-- Fivemanage (only if LogSystem = 'fivemanage')
FivemanageToken = "",
}

All display text lives in locales/*.lua. Select the active language with Config.Locale, or edit the values in the matching file to translate.

locales/en.lua
-- locales/en.lua
Locales['en'] = {
['ui_title'] = 'Wiretaps',
['ui_subtitle'] = 'Listening System',
['placing_bug'] = 'Placing a bug...',
['bug_placed_success'] = 'Bug placed successfully!',
['jammer_placed'] = 'Jammer placed!',
['amplifier_placed'] = 'Amplifier placed!',
['target_open_panel'] = 'Open wiretap panel',
-- ... see locales/en.lua for the full reference
}