[SUGGESTION] Feature Addition: Toggle HUD Command
The problem
I noticed qb-hud currently lacks a native way to programmatically hide/show the HUD, which is crucial for developers creating immersive UI experiences.
Ideal solution
This adds a new command /togglehud that allows players to completely hide/show the HUD and minimap. This feature is useful for:
Cinematic gameplay/screenshots Reducing screen clutter when needed Role-playing scenarios Content creation
Changes Made
Added server-side command /togglehud with player state tracking Added client-side toggle functionality Added export ToggleHud for other resources to use Properly handles minimap visibility based on vehicle state and menu settings Includes server-side notifications for command usage
Implementation Details
Maintains existing HUD settings when re-enabling Respects vehicle/on-foot minimap rules Doesn't interfere with existing HUD functionality Clean implementation using existing NUI messages Lightweight addition with minimal overhead
Testing
Tested functionality in the following scenarios:
On foot/in vehicle transitions Menu setting interactions Multiple toggle cycles Export usage from other resources Different notification states
NEW CLIENT CODE:
local QBCore = exports['qb-core']:GetCoreObject() local PlayerData = QBCore.Functions.GetPlayerData() local config = Config local speedMultiplier = config.UseMPH and 2.23694 or 3.6 local seatbeltOn = false local cruiseOn = false local showAltitude = false local showSeatbelt = false local nos = 0 local stress = 0 local hunger = 100 local thirst = 100 local cashAmount = 0 local bankAmount = 0 local nitroActive = 0 local harness = 0 local hp = 100 local armed = 0 local parachute = -1 local oxygen = 100 local dev = false local playerDead = false local showMenu = false local showCircleB = false local showSquareB = false local Menu = config.Menu local CinematicHeight = 0.2 local w = 0 local radioActive = false local isPauseMenuActive = false local hudHidden = false
-- HUD VISIBILITY
local function shouldDisplayRadar() if hudHidden then return false end if isPauseMenuActive then return false end if Menu.isHideMapChecked then return false end if Menu.isCinematicModeChecked then return false end
local player = PlayerPedId()
local vehicle = GetVehiclePedIsIn(player, false)
if IsPedInAnyVehicle(player) and not IsThisModelABicycle(vehicle) then
return true
end
return Menu.isOutMapChecked
end
-- HUD Visibility Toggle Function local function ToggleHudVisibility() hudHidden = not hudHidden
if hudHidden then
SendNUIMessage({
action = 'hudtick',
show = false
})
SendNUIMessage({
action = 'car',
show = false
})
SendNUIMessage({
action = 'baseplate',
show = false
})
DisplayRadar(false)
else
if not isPauseMenuActive then
SendNUIMessage({
action = 'hudtick',
show = true
})
DisplayRadar(shouldDisplayRadar())
end
end
end
-- Export Functions exports('ToggleHud', function() ToggleHudVisibility() end)
exports('SetHudState', function(state) if hudHidden ~= not state then ToggleHudVisibility() end DisplayRadar(shouldDisplayRadar()) end)
exports('IsHudHidden', function() return hudHidden end)
-- Event Handlers RegisterNetEvent('qb-hud:client:ToggleHud', function() ToggleHudVisibility() end)
DisplayRadar(false)
local function CinematicShow(bool) SetBigmapActive(true, false) Wait(0) SetBigmapActive(false, false) if bool then for i = CinematicHeight, 0, -1.0 do Wait(10) w = i end else for i = 0, CinematicHeight, 1.0 do Wait(10) w = i end end end
local function loadSettings(settings) for k, v in pairs(settings) do if k == 'isToggleMapShapeChecked' then Menu.isToggleMapShapeChecked = v SendNUIMessage({ test = true, event = k, toggle = v }) elseif k == 'isCinematicModeChecked' then Menu.isCinematicModeChecked = v CinematicShow(v) SendNUIMessage({ test = true, event = k, toggle = v }) elseif k == 'isChangeFPSChecked' then Menu[k] = v local val = v and 'Optimized' or 'Synced' SendNUIMessage({ test = true, event = k, toggle = val }) else Menu[k] = v SendNUIMessage({ test = true, event = k, toggle = v }) end end QBCore.Functions.Notify(Lang:t('notify.hud_settings_loaded'), 'success') Wait(1000) TriggerEvent('hud:client:LoadMap') end
local function saveSettings() SetResourceKvp('hudSettings', json.encode(Menu)) end
local function hasHarness(items) local ped = PlayerPedId() if not IsPedInAnyVehicle(ped, false) then return end
local _harness = false
if items then
for _, v in pairs(items) do
if v.name == 'harness' then
_harness = true
end
end
end
harness = _harness
end
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() Wait(2000) local hudSettings = GetResourceKvpString('hudSettings') if hudSettings then loadSettings(json.decode(hudSettings)) end PlayerData = QBCore.Functions.GetPlayerData() Wait(3000) SetEntityHealth(PlayerPedId(), 200) end)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() PlayerData = {} end)
RegisterNetEvent('QBCore:Player:SetPlayerData', function(val) PlayerData = val end)
AddEventHandler('onResourceStart', function(resourceName) if GetCurrentResourceName() ~= resourceName then return end Wait(2000) local hudSettings = GetResourceKvpString('hudSettings') if hudSettings then loadSettings(json.decode(hudSettings)) end end)
AddEventHandler('pma-voice:radioActive', function(data) radioActive = data end)
-- Callbacks & Events RegisterCommand('menu', function() Wait(50) if showMenu then return end TriggerEvent('hud:client:playOpenMenuSounds') SetNuiFocus(true, true) SendNUIMessage({ action = 'open' }) showMenu = true end)
RegisterNUICallback('closeMenu', function(_, cb) Wait(50) TriggerEvent('hud:client:playCloseMenuSounds') showMenu = false SetNuiFocus(false, false) cb('ok') end)
RegisterKeyMapping('menu', 'Open Menu', 'keyboard', config.OpenMenu)
-- Reset hud local function restartHud() TriggerEvent('hud:client:playResetHudSounds') QBCore.Functions.Notify(Lang:t('notify.hud_restart'), 'error') if IsPedInAnyVehicle(PlayerPedId()) then Wait(2600) SendNUIMessage({ action = 'car', show = false }) SendNUIMessage({ action = 'car', show = true }) end Wait(2600) SendNUIMessage({ action = 'hudtick', show = false }) SendNUIMessage({ action = 'hudtick', show = true }) Wait(2600) QBCore.Functions.Notify(Lang:t('notify.hud_start'), 'success') end
RegisterNUICallback('restartHud', function(_, cb) Wait(50) restartHud() cb('ok') end)
RegisterCommand('resethud', function() Wait(50) restartHud() end)
RegisterNUICallback('resetStorage', function(_, cb) Wait(50) TriggerEvent('hud:client:resetStorage') cb('ok') end)
RegisterNetEvent('hud:client:resetStorage', function() Wait(50) if Menu.isResetSoundsChecked then TriggerServerEvent('InteractSound_SV:PlayOnSource', 'airwrench', 0.1) end QBCore.Functions.TriggerCallback('hud:server:getMenu', function(menu) loadSettings(menu); SetResourceKvp('hudSettings', json.encode(menu)) end) end)
-- Notifications RegisterNUICallback('openMenuSounds', function(_, cb) Wait(50) Menu.isOpenMenuSoundsChecked = not Menu.isOpenMenuSoundsChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNetEvent('hud:client:playOpenMenuSounds', function() Wait(50) if not Menu.isOpenMenuSoundsChecked then return end TriggerServerEvent('InteractSound_SV:PlayOnSource', 'monkeyopening', 0.5) end)
RegisterNetEvent('hud:client:playCloseMenuSounds', function() Wait(50) if not Menu.isOpenMenuSoundsChecked then return end TriggerServerEvent('InteractSound_SV:PlayOnSource', 'catclosing', 0.05) end)
RegisterNUICallback('resetHudSounds', function(_, cb) Wait(50) Menu.isResetSoundsChecked = not Menu.isResetSoundsChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNetEvent('hud:client:playResetHudSounds', function() Wait(50) if not Menu.isResetSoundsChecked then return end TriggerServerEvent('InteractSound_SV:PlayOnSource', 'airwrench', 0.1) end)
RegisterNUICallback('checklistSounds', function(_, cb) Wait(50) TriggerEvent('hud:client:checklistSounds') cb('ok') end)
RegisterNetEvent('hud:client:checklistSounds', function() Wait(50) Menu.isListSoundsChecked = not Menu.isListSoundsChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() end)
RegisterNetEvent('hud:client:playHudChecklistSound', function() Wait(50) if not Menu.isListSoundsChecked then return end TriggerServerEvent('InteractSound_SV:PlayOnSource', 'shiftyclick', 0.5) end)
RegisterNUICallback('showOutMap', function(_, cb) Wait(50) Menu.isOutMapChecked = not Menu.isOutMapChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showOutCompass', function(_, cb) Wait(50) Menu.isOutCompassChecked = not Menu.isOutCompassChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showFollowCompass', function(_, cb) Wait(50) Menu.isCompassFollowChecked = not Menu.isCompassFollowChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showMapNotif', function(_, cb) Wait(50) Menu.isMapNotifChecked = not Menu.isMapNotifChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showFuelAlert', function(_, cb) Wait(50) Menu.isLowFuelChecked = not Menu.isLowFuelChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showCinematicNotif', function(_, cb) Wait(50) Menu.isCinematicNotifChecked = not Menu.isCinematicNotifChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
-- Status RegisterNUICallback('dynamicHealth', function(_, cb) Wait(50) TriggerEvent('hud:client:ToggleHealth') cb('ok') end)
RegisterNetEvent('hud:client:ToggleHealth', function() Wait(50) Menu.isDynamicHealthChecked = not Menu.isDynamicHealthChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() end)
RegisterNUICallback('dynamicArmor', function(_, cb) Wait(50) Menu.isDynamicArmorChecked = not Menu.isDynamicArmorChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('dynamicHunger', function(_, cb) Wait(50) Menu.isDynamicHungerChecked = not Menu.isDynamicHungerChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('dynamicThirst', function(_, cb) Wait(50) Menu.isDynamicThirstChecked = not Menu.isDynamicThirstChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('dynamicStress', function(_, cb) Wait(50) Menu.isDynamicStressChecked = not Menu.isDynamicStressChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('dynamicOxygen', function(_, cb) Wait(50) Menu.isDynamicOxygenChecked = not Menu.isDynamicOxygenChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
-- Vehicle RegisterNUICallback('changeFPS', function(_, cb) Wait(50) Menu.isChangeFPSChecked = not Menu.isChangeFPSChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('HideMap', function(_, cb) Wait(50) Menu.isHideMapChecked = not Menu.isHideMapChecked DisplayRadar(shouldDisplayRadar()) TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNetEvent('hud:client:LoadMap', function() Wait(50) -- Credit to Dalrae for the solve. local defaultAspectRatio = 1920 / 1080 -- Don't change this. local resolutionX, resolutionY = GetActiveScreenResolution() local aspectRatio = resolutionX / resolutionY local minimapOffset = 0 if aspectRatio > defaultAspectRatio then minimapOffset = ((defaultAspectRatio - aspectRatio) / 3.6) - 0.008 end if Menu.isToggleMapShapeChecked == 'square' then RequestStreamedTextureDict('squaremap', false) if not HasStreamedTextureDictLoaded('squaremap') then Wait(150) end if Menu.isMapNotifChecked then QBCore.Functions.Notify(Lang:t('notify.load_square_map')) end SetMinimapClipType(0) AddReplaceTexture('platform:/textures/graphics', 'radarmasksm', 'squaremap', 'radarmasksm') AddReplaceTexture('platform:/textures/graphics', 'radarmask1g', 'squaremap', 'radarmasksm') -- 0.0 = nav symbol and icons left -- 0.1638 = nav symbol and icons stretched -- 0.216 = nav symbol and icons raised up SetMinimapComponentPosition('minimap', 'L', 'B', 0.0 + minimapOffset, -0.047, 0.1638, 0.183)
-- icons within map
SetMinimapComponentPosition('minimap_mask', 'L', 'B', 0.0 + minimapOffset, 0.0, 0.128, 0.20)
-- -0.01 = map pulled left
-- 0.025 = map raised up
-- 0.262 = map stretched
-- 0.315 = map shorten
SetMinimapComponentPosition('minimap_blur', 'L', 'B', -0.01 + minimapOffset, 0.025, 0.262, 0.300)
SetBlipAlpha(GetNorthRadarBlip(), 0)
SetBigmapActive(true, false)
SetMinimapClipType(0)
Wait(50)
SetBigmapActive(false, false)
if Menu.isToggleMapBordersChecked then
showCircleB = false
showSquareB = true
end
Wait(1200)
if Menu.isMapNotifChecked then
QBCore.Functions.Notify(Lang:t('notify.loaded_square_map'))
end
elseif Menu.isToggleMapShapeChecked == 'circle' then
RequestStreamedTextureDict('circlemap', false)
if not HasStreamedTextureDictLoaded('circlemap') then
Wait(150)
end
if Menu.isMapNotifChecked then
QBCore.Functions.Notify(Lang:t('notify.load_circle_map'))
end
SetMinimapClipType(1)
AddReplaceTexture('platform:/textures/graphics', 'radarmasksm', 'circlemap', 'radarmasksm')
AddReplaceTexture('platform:/textures/graphics', 'radarmask1g', 'circlemap', 'radarmasksm')
-- -0.0100 = nav symbol and icons left
-- 0.180 = nav symbol and icons stretched
-- 0.258 = nav symbol and icons raised up
SetMinimapComponentPosition('minimap', 'L', 'B', -0.0100 + minimapOffset, -0.030, 0.180, 0.258)
-- icons within map
SetMinimapComponentPosition('minimap_mask', 'L', 'B', 0.200 + minimapOffset, 0.0, 0.065, 0.20)
-- -0.00 = map pulled left
-- 0.015 = map raised up
-- 0.252 = map stretched
-- 0.338 = map shorten
SetMinimapComponentPosition('minimap_blur', 'L', 'B', -0.00 + minimapOffset, 0.015, 0.252, 0.338)
SetBlipAlpha(GetNorthRadarBlip(), 0)
SetMinimapClipType(1)
SetBigmapActive(true, false)
Wait(50)
SetBigmapActive(false, false)
if Menu.isToggleMapBordersChecked then
showSquareB = false
showCircleB = true
end
Wait(1200)
if Menu.isMapNotifChecked then
QBCore.Functions.Notify(Lang:t('notify.loaded_circle_map'))
end
end
end)
RegisterNUICallback('ToggleMapShape', function(_, cb) Wait(50) if not Menu.isHideMapChecked then Menu.isToggleMapShapeChecked = Menu.isToggleMapShapeChecked == 'circle' and 'square' or 'circle' Wait(50) TriggerEvent('hud:client:LoadMap') end TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('ToggleMapBorders', function(_, cb) Wait(50) Menu.isToggleMapBordersChecked = not Menu.isToggleMapBordersChecked if Menu.isToggleMapBordersChecked then if Menu.isToggleMapShapeChecked == 'square' then showSquareB = true else showCircleB = true end else showSquareB = false showCircleB = false end TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('dynamicEngine', function(_, cb) Wait(50) Menu.isDynamicEngineChecked = not Menu.isDynamicEngineChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('dynamicNitro', function(_, cb) Wait(50) Menu.isDynamicNitroChecked = not Menu.isDynamicNitroChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
-- Compass RegisterNUICallback('showCompassBase', function(_, cb) Wait(50) Menu.isCompassShowChecked = not Menu.isCompassShowChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showStreetsNames', function(_, cb) Wait(50) Menu.isShowStreetsChecked = not Menu.isShowStreetsChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showPointerIndex', function(_, cb) Wait(50) Menu.isPointerShowChecked = not Menu.isPointerShowChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('showDegreesNum', function(_, cb) Wait(50) Menu.isDegreesShowChecked = not Menu.isDegreesShowChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('changeCompassFPS', function(_, cb) Wait(50) Menu.isChangeCompassFPSChecked = not Menu.isChangeCompassFPSChecked TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNUICallback('cinematicMode', function(_, cb) Wait(50) if Menu.isCinematicModeChecked then CinematicShow(false) Menu.isCinematicModeChecked = false if Menu.isCinematicNotifChecked then QBCore.Functions.Notify(Lang:t('notify.cinematic_off'), 'error') end DisplayRadar(1) else CinematicShow(true) Menu.isCinematicModeChecked = true if Menu.isCinematicNotifChecked then QBCore.Functions.Notify(Lang:t('notify.cinematic_on')) end end TriggerEvent('hud:client:playHudChecklistSound') saveSettings() cb('ok') end)
RegisterNetEvent('hud:client:ToggleAirHud', function() showAltitude = not showAltitude end)
RegisterNetEvent('hud:client:UpdateNeeds', function(newHunger, newThirst) -- Triggered in qb-core hunger = newHunger thirst = newThirst end)
RegisterNetEvent('hud:client:UpdateStress', function(newStress) -- Add this event with adding stress elsewhere stress = newStress end)
RegisterNetEvent('hud:client:ToggleShowSeatbelt', function() showSeatbelt = not showSeatbelt end)
RegisterNetEvent('seatbelt:client:ToggleSeatbelt', function() -- Triggered in smallresources seatbeltOn = not seatbeltOn end)
RegisterNetEvent('seatbelt:client:ToggleCruise', function() -- Triggered in smallresources cruiseOn = not cruiseOn end)
RegisterNetEvent('hud:client:UpdateNitrous', function(nitroLevel, bool) nos = nitroLevel nitroActive = bool end)
RegisterNetEvent('hud:client:UpdateHarness', function(harnessHp) hp = harnessHp end)
RegisterNetEvent('qb-admin:client:ToggleDevmode', function() dev = not dev end)
local prevPlayerStats = { nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil }
local function updatePlayerHud(data) local shouldUpdate = false for k, v in pairs(data) do if prevPlayerStats[k] ~= v then shouldUpdate = true break end end prevPlayerStats = data if shouldUpdate then SendNUIMessage({ action = 'hudtick', show = data[1], dynamicHealth = data[2], dynamicArmor = data[3], dynamicHunger = data[4], dynamicThirst = data[5], dynamicStress = data[6], dynamicOxygen = data[7], dynamicEngine = data[8], dynamicNitro = data[9], health = data[10], playerDead = data[11], armor = data[12], thirst = data[13], hunger = data[14], stress = data[15], voice = data[16], radio = data[17], talking = data[18], armed = data[19], oxygen = data[20], parachute = data[21], nos = data[22], cruise = data[23], nitroActive = data[24], harness = data[25], hp = data[26], speed = data[27], engine = data[28], cinematic = data[29], dev = data[30], radioActive = data[31], }) end end
local prevVehicleStats = { nil, nil, nil, nil, nil, nil, nil, nil, nil, nil }
local function updateVehicleHud(data) local shouldUpdate = false for k, v in pairs(data) do if prevVehicleStats[k] ~= v then shouldUpdate = true break end end prevVehicleStats = data if shouldUpdate then SendNUIMessage({ action = 'car', show = data[1], isPaused = data[2], seatbelt = data[3], speed = data[4], fuel = data[5], altitude = data[6], showAltitude = data[7], showSeatbelt = data[8], showSquareB = data[9], showCircleB = data[10], }) end end
local lastFuelUpdate = 0 local lastFuelCheck = {}
local function getFuelLevel(vehicle) local updateTick = GetGameTimer() if (updateTick - lastFuelUpdate) > 2000 then lastFuelUpdate = updateTick lastFuelCheck = math.floor(exports['LegacyFuel']:GetFuel(vehicle)) end return lastFuelCheck end
-- HUD Update loop -- UPDATED TO RESPECT THE HUD HIDDEN STATE CreateThread(function() local wasInVehicle = false while true do if Menu.isChangeFPSChecked then Wait(500) else Wait(50) end
if LocalPlayer.state.isLoggedIn then
local show = not hudHidden
local player = PlayerPedId()
local playerId = PlayerId()
-- Check pause menu state
local currentPauseState = IsPauseMenuActive()
if currentPauseState ~= isPauseMenuActive then
isPauseMenuActive = currentPauseState
if isPauseMenuActive then
show = false
end
DisplayRadar(shouldDisplayRadar())
end
-- If pause menu is active, hide HUD elements
if isPauseMenuActive then
show = false
SendNUIMessage({
action = 'hudtick',
show = false
})
SendNUIMessage({
action = 'car',
show = false
})
Wait(100)
goto continue
end
local weapon = GetSelectedPedWeapon(player)
if not config.WhitelistedWeaponArmed[weapon] then
if weapon ~= `WEAPON_UNARMED` then
armed = true
else
armed = false
end
end
playerDead = IsEntityDead(player) or PlayerData.metadata['inlaststand'] or PlayerData.metadata['isdead'] or false
parachute = GetPedParachuteState(player)
-- Stamina
if not IsEntityInWater(player) then
oxygen = 100 - GetPlayerSprintStaminaRemaining(playerId)
end
-- Oxygen
if IsEntityInWater(player) then
oxygen = GetPlayerUnderwaterTimeRemaining(playerId) * 10
end
local talking = NetworkIsPlayerTalking(playerId)
local voice = 0
if LocalPlayer.state['proximity'] then
voice = LocalPlayer.state['proximity'].distance
end
local vehicle = GetVehiclePedIsIn(player)
if not (IsPedInAnyVehicle(player) and not IsThisModelABicycle(vehicle)) then
updatePlayerHud({
show,
Menu.isDynamicHealthChecked,
Menu.isDynamicArmorChecked,
Menu.isDynamicHungerChecked,
Menu.isDynamicThirstChecked,
Menu.isDynamicStressChecked,
Menu.isDynamicOxygenChecked,
Menu.isDynamicEngineChecked,
Menu.isDynamicNitroChecked,
GetEntityHealth(player) - 100,
playerDead,
GetPedArmour(player),
thirst,
hunger,
stress,
voice,
LocalPlayer.state['radioChannel'],
talking,
armed,
oxygen,
parachute,
-1,
cruiseOn,
nitroActive,
harness,
hp,
math.ceil(GetEntitySpeed(vehicle) * speedMultiplier),
-1,
Menu.isCinematicModeChecked,
dev,
radioActive
})
end
-- Vehicle HUD
if IsPedInAnyHeli(player) or IsPedInAnyPlane(player) then
showAltitude = true
showSeatbelt = false
end
if IsPedInAnyVehicle(player) and not IsThisModelABicycle(vehicle) then
if not wasInVehicle then
wasInVehicle = true
DisplayRadar(shouldDisplayRadar())
end
local engineHealth = GetVehicleEngineHealth(vehicle)
if engineHealth ~= engineHealth then
engineHealth = 0
end
updatePlayerHud({
show,
Menu.isDynamicHealthChecked,
Menu.isDynamicArmorChecked,
Menu.isDynamicHungerChecked,
Menu.isDynamicThirstChecked,
Menu.isDynamicStressChecked,
Menu.isDynamicOxygenChecked,
Menu.isDynamicEngineChecked,
Menu.isDynamicNitroChecked,
GetEntityHealth(player) - 100,
playerDead,
GetPedArmour(player),
thirst,
hunger,
stress,
voice,
LocalPlayer.state['radioChannel'],
talking,
armed,
oxygen,
GetPedParachuteState(player),
nos,
cruiseOn,
nitroActive,
harness,
hp,
math.ceil(GetEntitySpeed(vehicle) * speedMultiplier),
(engineHealth / 10),
Menu.isCinematicModeChecked,
dev,
radioActive
})
updateVehicleHud({
show,
isPauseMenuActive,
seatbeltOn,
math.ceil(GetEntitySpeed(vehicle) * speedMultiplier),
getFuelLevel(vehicle),
math.ceil(GetEntityCoords(player).z * 0.5),
showAltitude,
showSeatbelt,
showSquareB,
showCircleB
})
showAltitude = false
showSeatbelt = true
else
if wasInVehicle then
wasInVehicle = false
SendNUIMessage({
action = 'car',
show = false,
seatbelt = false,
cruise = false,
})
seatbeltOn = false
cruiseOn = false
harness = false
end
DisplayRadar(shouldDisplayRadar())
end
::continue::
else
SendNUIMessage({
action = 'hudtick',
show = false
})
DisplayRadar(false)
end
end
end)
-- Low fuel CreateThread(function() while true do if LocalPlayer.state.isLoggedIn then local ped = PlayerPedId() if IsPedInAnyVehicle(ped, false) and not IsThisModelABicycle(GetEntityModel(GetVehiclePedIsIn(ped, false))) then if exports['LegacyFuel']:GetFuel(GetVehiclePedIsIn(ped, false)) <= 20 then -- At 20% Fuel Left if Menu.isLowFuelChecked then TriggerServerEvent('InteractSound_SV:PlayOnSource', 'pager', 0.10) QBCore.Functions.Notify(Lang:t('notify.low_fuel'), 'error') Wait(60000) -- repeats every 1 min until empty end end end end Wait(10000) end end)
-- Money HUD
local Round = math.floor
RegisterNetEvent('hud:client:ShowAccounts', function(type, amount) if type == 'cash' then SendNUIMessage({ action = 'show', type = 'cash', cash = Round(amount) }) else SendNUIMessage({ action = 'show', type = 'bank', bank = Round(amount) }) end end)
RegisterNetEvent('hud:client:OnMoneyChange', function(type, amount, isMinus) cashAmount = PlayerData.money['cash'] bankAmount = PlayerData.money['bank'] SendNUIMessage({ action = 'updatemoney', cash = Round(cashAmount), bank = Round(bankAmount), amount = Round(amount), minus = isMinus, type = type }) end)
-- Harness Check
CreateThread(function() while true do Wait(1000)
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
hasHarness(PlayerData.items)
end
end
end)
-- Stress Gain
if not config.DisableStress then CreateThread(function() -- Speeding while true do if LocalPlayer.state.isLoggedIn then local ped = PlayerPedId() if IsPedInAnyVehicle(ped, false) then local veh = GetVehiclePedIsIn(ped, false) local vehClass = GetVehicleClass(veh) local speed = GetEntitySpeed(veh) * speedMultiplier local vehHash = GetEntityModel(veh) if config.VehClassStress[tostring(vehClass)] and not config.WhitelistedVehicles[vehHash] then local stressSpeed if vehClass == 8 then -- Motorcycle exception for seatbelt stressSpeed = config.MinimumSpeed else stressSpeed = seatbeltOn and config.MinimumSpeed or config.MinimumSpeedUnbuckled end if speed >= stressSpeed then TriggerServerEvent('hud:server:GainStress', math.random(1, 3)) end end end end Wait(10000) end end)
CreateThread(function() -- Shooting
while true do
if LocalPlayer.state.isLoggedIn then
local ped = PlayerPedId()
local weapon = GetSelectedPedWeapon(ped)
if weapon ~= `WEAPON_UNARMED` then
if IsPedShooting(ped) and not config.WhitelistedWeaponStress[weapon] then
if math.random() < config.StressChance then
TriggerServerEvent('hud:server:GainStress', math.random(1, 3))
end
end
else
Wait(1000)
end
end
Wait(0)
end
end)
end
-- Stress Screen Effects
local function GetBlurIntensity(stresslevel) for _, v in pairs(config.Intensity['blur']) do if stresslevel >= v.min and stresslevel <= v.max then return v.intensity end end return 1500 end
local function GetEffectInterval(stresslevel) for _, v in pairs(config.EffectInterval) do if stresslevel >= v.min and stresslevel <= v.max then return v.timeout end end return 60000 end
CreateThread(function() while true do local ped = PlayerPedId() local effectInterval = GetEffectInterval(stress) if stress >= 100 then local BlurIntensity = GetBlurIntensity(stress) local FallRepeat = math.random(2, 4) local RagdollTimeout = FallRepeat * 1750 TriggerScreenblurFadeIn(1000.0) Wait(BlurIntensity) TriggerScreenblurFadeOut(1000.0)
if not IsPedRagdoll(ped) and IsPedOnFoot(ped) and not IsPedSwimming(ped) then
SetPedToRagdollWithFall(ped, RagdollTimeout, RagdollTimeout, 1, GetEntityForwardVector(ped), 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
end
Wait(1000)
for _ = 1, FallRepeat, 1 do
Wait(750)
DoScreenFadeOut(200)
Wait(1000)
DoScreenFadeIn(200)
TriggerScreenblurFadeIn(1000.0)
Wait(BlurIntensity)
TriggerScreenblurFadeOut(1000.0)
end
elseif stress >= config.MinimumStress then
local BlurIntensity = GetBlurIntensity(stress)
TriggerScreenblurFadeIn(1000.0)
Wait(BlurIntensity)
TriggerScreenblurFadeOut(1000.0)
end
Wait(effectInterval)
end
end)
-- Minimap update CreateThread(function() while true do SetBigmapActive(false, false) SetRadarZoom(1000) Wait(500) end end)
local function BlackBars() DrawRect(0.0, 0.0, 2.0, w, 0, 0, 0, 255) DrawRect(0.0, 1.0, 2.0, w, 0, 0, 0, 255) end
CreateThread(function() local minimap = RequestScaleformMovie('minimap') if not HasScaleformMovieLoaded(minimap) then RequestScaleformMovie(minimap) while not HasScaleformMovieLoaded(minimap) do Wait(1) end end while true do if w > 0 then BlackBars() DisplayRadar(0) SendNUIMessage({ action = 'hudtick', show = false, }) SendNUIMessage({ action = 'car', show = false, }) end Wait(0) end end)
-- Compass function round(num, numDecimalPlaces) local mult = 10 ^ (numDecimalPlaces or 0) return math.floor(num + 0.5 * mult) end
local prevBaseplateStats = { nil, nil, nil, nil, nil, nil, nil }
local function updateBaseplateHud(data) local shouldUpdate = false for k, v in pairs(data) do if prevBaseplateStats[k] ~= v then shouldUpdate = true break end end prevBaseplateStats = data if shouldUpdate then SendNUIMessage({ action = 'baseplate', show = data[1], street1 = data[2], street2 = data[3], showCompass = data[4], showStreets = data[5], showPointer = data[6], showDegrees = data[7], }) end end
local lastCrossroadUpdate = 0 local lastCrossroadCheck = {}
local function getCrossroads(player) local updateTick = GetGameTimer() if updateTick - lastCrossroadUpdate > 1500 then local pos = GetEntityCoords(player) local street1, street2 = GetStreetNameAtCoord(pos.x, pos.y, pos.z) lastCrossroadUpdate = updateTick lastCrossroadCheck = { GetStreetNameFromHashKey(street1), GetStreetNameFromHashKey(street2) } end return lastCrossroadCheck end
-- Compass Update loop
CreateThread(function() local lastHeading = 1 local heading while true do if Menu.isChangeCompassFPSChecked then Wait(50) else Wait(0) end local show = true local player = PlayerPedId() local camRot = GetGameplayCamRot(0) if Menu.isCompassFollowChecked then heading = tostring(round(360.0 - ((camRot.z + 360.0) % 360.0))) else heading = tostring(round(360.0 - GetEntityHeading(player))) end if heading == '360' then heading = '0' end if heading ~= lastHeading then if IsPedInAnyVehicle(player) then local crossroads = getCrossroads(player) SendNUIMessage({ action = 'update', value = heading }) updateBaseplateHud({ show, crossroads[1], crossroads[2], Menu.isCompassShowChecked, Menu.isShowStreetsChecked, Menu.isPointerShowChecked, Menu.isDegreesShowChecked, }) else if Menu.isOutCompassChecked then SendNUIMessage({ action = 'update', value = heading }) SendNUIMessage({ action = 'baseplate', show = true, showCompass = true, }) else SendNUIMessage({ action = 'baseplate', show = false, }) end end end lastHeading = heading end end)
NEW SERVER CODE:
local QBCore = exports['qb-core']:GetCoreObject() local ResetStress = false local hiddenStates = {} -- Added Variable to track hud toggle state (On/Off)
QBCore.Commands.Add('cash', 'Check Cash Balance', {}, false, function(source, _) local Player = QBCore.Functions.GetPlayer(source) local cashamount = Player.PlayerData.money.cash TriggerClientEvent('hud:client:ShowAccounts', source, 'cash', cashamount) end)
QBCore.Commands.Add('bank', 'Check Bank Balance', {}, false, function(source, _) local Player = QBCore.Functions.GetPlayer(source) local bankamount = Player.PlayerData.money.bank TriggerClientEvent('hud:client:ShowAccounts', source, 'bank', bankamount) end)
QBCore.Commands.Add('dev', 'Enable/Disable developer Mode', {}, false, function(source, _) TriggerClientEvent('qb-admin:client:ToggleDevmode', source) end, 'admin')
RegisterNetEvent('hud:server:GainStress', function(amount) if Config.DisableStress then return end local src = source local Player = QBCore.Functions.GetPlayer(src) local Job = Player.PlayerData.job.name local JobType = Player.PlayerData.job.type local newStress if not Player or Config.WhitelistedJobs[JobType] or Config.WhitelistedJobs[Job] then return end if not ResetStress then if not Player.PlayerData.metadata['stress'] then Player.PlayerData.metadata['stress'] = 0 end newStress = Player.PlayerData.metadata['stress'] + amount if newStress <= 0 then newStress = 0 end else newStress = 0 end if newStress > 100 then newStress = 100 end Player.Functions.SetMetaData('stress', newStress) TriggerClientEvent('hud:client:UpdateStress', src, newStress) TriggerClientEvent('QBCore:Notify', src, Lang:t('notify.stress_gain'), 'error', 1500) end)
RegisterNetEvent('hud:server:RelieveStress', function(amount) if Config.DisableStress then return end local src = source local Player = QBCore.Functions.GetPlayer(src) local newStress if not Player then return end if not ResetStress then if not Player.PlayerData.metadata['stress'] then Player.PlayerData.metadata['stress'] = 0 end newStress = Player.PlayerData.metadata['stress'] - amount if newStress <= 0 then newStress = 0 end else newStress = 0 end if newStress > 100 then newStress = 100 end Player.Functions.SetMetaData('stress', newStress) TriggerClientEvent('hud:client:UpdateStress', src, newStress) TriggerClientEvent('QBCore:Notify', src, Lang:t('notify.stress_removed')) end)
QBCore.Functions.CreateCallback('hud:server:getMenu', function(_, cb) cb(Config.Menu) end)
local function ToggleHudForPlayer(source, shouldHide) TriggerClientEvent('qb-hud:client:ToggleHud', source, shouldHide) end
exports('ToggleHudForPlayer', ToggleHudForPlayer)
QBCore.Commands.Add('togglehud', 'Toggle HUD visibility', {}, false, function(source) hiddenStates[source] = not hiddenStates[source] if hiddenStates[source] then TriggerClientEvent('QBCore:Notify', source, 'HUD Hidden', 'error') else TriggerClientEvent('QBCore:Notify', source, 'HUD Visible', 'success') end
-- Trigger the client event to actually toggle the HUD
TriggerClientEvent('qb-hud:client:ToggleHud', source)
end)
-- Add player cleanup when they disconnect AddEventHandler('playerDropped', function() local source = source hiddenStates[source] = nil end)