local ox_inventory = exports.ox_inventory local isSearching = false local textUiShowing = false -- ========================================== -- EXPORTI ZA DRUGE SKRIPTE -- ========================================== exports('GiveKeys', function(plate, model, notify) TriggerServerEvent('adv-vehiclekeys:server:GiveKeys', plate, model, notify) end) exports('RemoveKeys', function(plate, model) TriggerServerEvent('adv-vehiclekeys:server:RemoveKeys', plate, model) end) -- ========================================== -- POMOŽNE FUNKCIJE IN EXPORTI -- ========================================== local function GetKey(plate) if not plate then return false end local cleanSearchPlate = string.match(plate, "^%s*(.-)%s*$") local items = ox_inventory:Search('slots', 'vehiclekeys') for _, item in pairs(items) do if item.metadata and item.metadata.plate then local cleanItemPlate = string.match(item.metadata.plate, "^%s*(.-)%s*$") if cleanItemPlate == cleanSearchPlate then return true end end end return false end exports('GetKey', GetKey) -- Animacija za ključ (U) local function ToggleVehicleLock(veh) local lockStatus = GetVehicleDoorLockStatus(veh) local ped = PlayerPedId() local animDict = "anim@mp_player_intmenu@key_fob@" RequestAnimDict(animDict) while not HasAnimDictLoaded(animDict) do Wait(10) end TaskPlayAnim(ped, animDict, "fob_click", 8.0, 8.0, -1, 48, 1, false, false, false) Wait(500) if lockStatus == 1 or lockStatus == 0 then SetVehicleDoorsLocked(veh, 2) SetVehicleLights(veh, 2) Wait(200) SetVehicleLights(veh, 0) Wait(200) SetVehicleLights(veh, 2) Wait(200) SetVehicleLights(veh, 0) lib.notify({ title = 'Vozilo', description = 'Vozilo je zaklenjeno.', type = 'error', icon = 'lock' }) else SetVehicleDoorsLocked(veh, 1) SetVehicleLights(veh, 2) Wait(200) SetVehicleLights(veh, 0) Wait(200) SetVehicleLights(veh, 2) Wait(200) SetVehicleLights(veh, 0) lib.notify({ title = 'Vozilo', description = 'Vozilo je odklenjeno.', type = 'success', icon = 'lock-open' }) end RemoveAnimDict(animDict) end -- ========================================== -- 1. KORAK: LOCKPICK (SAMO ZA VRATA) -- ========================================== exports('useCarlockpick', function(data, slot) local ped = PlayerPedId() local coords = GetEntityCoords(ped) local veh = lib.getClosestVehicle(coords, 3.0, false) if veh and veh ~= 0 then local lockStatus = GetVehicleDoorLockStatus(veh) if lockStatus == 1 or lockStatus == 0 then lib.notify({ title = 'Info', description = 'Vrata so že odklenjena.', type = 'info' }) return end CreateThread(function() TaskTurnPedToFaceEntity(ped, veh, 1000) Wait(1000) local dict = Config.LockpickAnim.dict local anim = Config.LockpickAnim.anim RequestAnimDict(dict) while not HasAnimDictLoaded(dict) do Wait(10) end TaskPlayAnim(ped, dict, anim, 3.0, 3.0, -1, 1, 0, false, false, false) local success = lib.skillCheck(Config.LockpickSkillCheck) ClearPedTasks(ped) RemoveAnimDict(dict) if success then -- KLJUČNI POPRAVEK: Skripti povemo, da je bil ta avto že ročno obdelan. -- Glavna zanka ga sedaj ne bo več poskušala naključno zakleniti! Entity(veh).state.lockChecked = true SetVehicleDoorsLocked(veh, 1) SetVehicleDoorsLockedForAllPlayers(veh, false) lib.notify({ title = 'Uspeh', description = 'Odklenili ste vrata. Zdaj vstopite in poiščite ključe.', type = 'success', icon = 'unlock' }) else lib.notify({ title = 'Neuspeh', description = 'Lockpick se je zlomil!', type = 'error' }) -- Kličemo server, da igralcu vzame 1x lockpick TriggerServerEvent('adv-vehiclekeys:server:breakLockpick') end end) else lib.notify({ title = 'Napaka', description = 'Nobenega vozila ni v bližini.', type = 'error' }) end end) -- ========================================== -- 2. KORAK: ISKANJE KLJUČEV V VOZILU -- ========================================== RegisterCommand('search_veh_key', function() if not Config.SearchKey or isSearching then return end local ped = PlayerPedId() local veh = GetVehiclePedIsIn(ped, false) if veh ~= 0 and GetPedInVehicleSeat(veh, -1) == ped then local plate = GetVehicleNumberPlateText(veh) -- Če že ima ključ, mu ne pustimo iskati if GetKey(plate) then lib.notify({ title = 'Info', description = 'Ključe od tega vozila že imate.', type = 'info' }) return end CreateThread(function() isSearching = true if textUiShowing then lib.hideTextUI() textUiShowing = false end lib.notify({ title = 'Iskanje', description = 'Iščete ključe po vozilu...', type = 'info' }) -- Mini igra preden začne brskati local success = lib.skillCheck(Config.SearchKeySkillCheck) if success then -- Okenček z animacijo, ki napolni progress bar if lib.progressBar({ duration = Config.SearchKeyProgress.duration, label = Config.SearchKeyProgress.label, useWhileDead = false, canCancel = true, disable = { car = false, move = false }, anim = { dict = Config.SearchAnim.dict, clip = Config.SearchAnim.anim, flag = 49 -- 49 omogoča animacijo samo zgornjega dela telesa (da lahko sedi v avtu) } }) then -- Če progress bar pride do konca, igralec DOBI ključ! local model = GetDisplayNameFromVehicleModel(GetEntityModel(veh)) TriggerServerEvent('adv-vehiclekeys:server:GiveKeys', plate, model, true) lib.notify({ title = 'Uspeh', description = 'Našli ste ključe! Pritisnite M za vžig motorja.', type = 'success' }) else lib.notify({ title = 'Preklic', description = 'Prenehali ste z iskanjem.', type = 'error' }) end else lib.notify({ title = 'Neuspeh', description = 'Niste našli ničesar koristnega.', type = 'error' }) end Wait(500) isSearching = false end) end end) RegisterKeyMapping('search_veh_key', 'Poišči ključe v vozilu', 'keyboard', Config.UseSearchKey) -- ========================================== -- KOMANDE ZA KLJUČ IN MOTOR -- ========================================== RegisterCommand('toggle_veh_lock', function() local ped = PlayerPedId() local veh = GetVehiclePedIsIn(ped, false) if veh == 0 then veh = lib.getClosestVehicle(GetEntityCoords(ped), 5.0, false) end if veh and veh ~= 0 then local plate = GetVehicleNumberPlateText(veh) if GetKey(plate) then ToggleVehicleLock(veh) else lib.notify({ title = 'Napaka', description = 'Nimate ključev. Uporabite lockpick za vrata.', type = 'error' }) end else lib.notify({ title = 'Napaka', description = 'Vozilo ni v bližini.', type = 'error' }) end end) RegisterKeyMapping('toggle_veh_lock', 'Zakleni/Odkleni', 'keyboard', Config.Controls.UseKey) RegisterCommand('toggle_veh_engine', function() local ped = PlayerPedId() local veh = GetVehiclePedIsIn(ped, false) if veh ~= 0 and GetPedInVehicleSeat(veh, -1) == ped then local plate = GetVehicleNumberPlateText(veh) if GetKey(plate) then local isRunning = GetIsVehicleEngineRunning(veh) SetVehicleEngineOn(veh, not isRunning, false, true) else lib.notify({ title = 'Napaka', description = 'Nimate ključev za vžig (Poišči jih s tipko H).', type = 'error' }) end end end) RegisterKeyMapping('toggle_veh_engine', 'Motor', 'keyboard', Config.Controls.EngineControl) -- ========================================== -- MAIN LOOP (PREVERJANJE STANJA) -- ========================================== CreateThread(function() local lastVeh = 0 while true do Wait(0) local ped = PlayerPedId() local veh = GetVehiclePedIsIn(ped, false) if veh ~= 0 and GetPedInVehicleSeat(veh, -1) == ped then local plate = GetVehicleNumberPlateText(veh) local hasKey = GetKey(plate) if lastVeh ~= veh then SetVehicleNeedsToBeHotwired(veh, false) SetVehicleEngineOn(veh, GetIsVehicleEngineRunning(veh), false, true) lastVeh = veh end if not GetIsVehicleEngineRunning(veh) and Config.DisableControlAction then DisableControlAction(0, 71, true) DisableControlAction(0, 72, true) end -- Če NIMA KLJUČA if not hasKey then if GetIsVehicleEngineRunning(veh) then SetVehicleEngineOn(veh, false, false, true) end if not isSearching and not textUiShowing then lib.showTextUI('[H] - Poišči ključe', { position = 'right-center', icon = 'magnifying-glass' }) textUiShowing = true end else if textUiShowing then lib.hideTextUI() textUiShowing = false end end else if lastVeh ~= 0 then lastVeh = 0 end if textUiShowing then lib.hideTextUI() textUiShowing = false end end local enteringVeh = GetVehiclePedIsTryingToEnter(ped) if enteringVeh ~= 0 then if not Entity(enteringVeh).state.lockChecked then Entity(enteringVeh).state.lockChecked = true if math.random(1, 100) <= Config.NPCLockChance then SetVehicleDoorsLocked(enteringVeh, 2) end end end end end) -- Target Sistem CreateThread(function() exports.ox_target:addGlobalVehicle({ { name = 'lock_target', icon = 'fas fa-key', label = 'Odkleni / Zakleni', canInteract = function(entity) return GetKey(GetVehicleNumberPlateText(entity)) end, onSelect = function(data) ToggleVehicleLock(data.entity) end } }) end)