local config = require 'config.client' local playerState = LocalPlayer.state local speedMultiplier = config.useMPH and 2.237 or 3.6 local minSpeeds = { unbuckled = config.minSpeedUnbuckled / speedMultiplier, buckled = config.minSpeedBuckled / speedMultiplier, harness = config.harness.minSpeed / speedMultiplier } -- Functions local function playBuckleSound() local maxAttempts = 3 local attempt = 0 local success = false while attempt < maxAttempts and not success do attempt = attempt + 1 success = lib.waitFor(function() return lib.loadAudioBank('audiodirectory/seatbelt_sounds') end, 'Failed to load seatbelt audio bank', 1000) if success then if IsSoundPlayed then StopSound(IsSoundPlayed) end PlaySoundFrontend(-1, buckle and "Buckle" or "Unbuckle", "Seatbelt_SoundSet", true) return true end if attempt < maxAttempts then Wait(500) -- Wait before retry end end if not success then print('^3Warning: Could not load seatbelt sound after ' .. maxAttempts .. ' attempts^7') return false end end local function toggleSeatbelt() if not IsPedInAnyVehicle(cache.ped, false) then return end buckle = not buckle -- Attempt to play sound but continue even if it fails local soundPlayed = playBuckleSound() if not soundPlayed then -- Continue with seatbelt logic even if sound failed print('^3Warning: Proceeding without seatbelt sound^7') end SetFlyThroughWindscreenParams(windscreenDamageOffset, windscreenDamageMult, beltOffset, beltMult, buckle and 1.0 or 0.0) SendNUIMessage({ action = 'seatbelt', value = buckle }) end local function toggleHarness() local harnessOn = not playerState.harness playerState.harness = harnessOn TriggerEvent('seatbelt:client:ToggleSeatbelt') playBuckleSound() local canFlyThroughWindscreen = not harnessOn if config.harness.disableFlyingThroughWindscreen then SetPedConfigFlag(cache.ped, 32, canFlyThroughWindscreen) -- PED_FLAG_CAN_FLY_THRU_WINDSCREEN else local minSpeed = harnessOn and minSpeeds.harness or (playerState.seatbelt and minSpeeds.buckled or minSpeeds.unbuckled) SetFlyThroughWindscreenParams(minSpeed, 1.0, 17.0, 10.0) end end local function seatbelt() while cache.vehicle do local sleep = 1000 if playerState.seatbelt or playerState.harness then sleep = 0 DisableControlAction(0, 75, true) DisableControlAction(27, 75, true) end Wait(sleep) end playerState.seatbelt = false playerState.harness = false end -- Export function HasHarness() return playerState.harness end --- @deprecated Use `state.seatbelt` instead exports('HasHarness', HasHarness) -- Main Thread CreateThread(function() SetFlyThroughWindscreenParams(minSpeeds.unbuckled, 1.0, 17.0, 10.0) end) lib.onCache('vehicle', function() Wait(500) seatbelt() end) -- Events RegisterNetEvent('qbx_seatbelt:client:UseHarness', function(ItemData) if playerState.seatbelt then exports.qbx_core:Notify(locale('error.seatbelton'), 'error') return end local class = GetVehicleClass(cache.vehicle) if not cache.vehicle or class == 8 or class == 13 or class == 14 then exports.qbx_core:Notify(locale('notify.notInCar'), 'error') return end if not playerState.harness then if lib.progressCircle({ duration = 5000, label = locale('progress.attachHarness'), position = 'bottom', useWhileDead = false, canCancel = true, disable = { combat = true } }) then TriggerServerEvent('qbx_seatbelt:server:equip', ItemData.slot) toggleHarness() end else if lib.progressCircle({ duration = 5000, label = locale('progress.removeHarness'), position = 'bottom', useWhileDead = false, canCancel = true, disable = { combat = true } }) then toggleHarness() end end end) -- Register Key lib.addKeybind({ name = 'toggleseatbelt', description = locale('toggleCommand'), defaultKey = config.keybind, onPressed = function() if not cache.vehicle or IsPauseMenuActive() then return end local class = GetVehicleClass(cache.vehicle) if class == 8 or class == 13 or class == 14 then return end toggleSeatbelt() end })