Config.TargetSystem = nil if GetResourceState("qb-target") ~= "missing" then Config.TargetSystem = "qb-target" elseif GetResourceState("qtarget") ~= "missing" then Config.TargetSystem = "qtarget" elseif GetResourceState("ox_target") ~= "missing" then Config.TargetSystem = "qtarget" -- OX_Target have a backward compability to qtarget end -- Animatie tableta pentru meniul Job Center local tabletProp = nil local animDict = "amb@code_human_in_bus_passenger_idles@female@tablet@base" local animName = "base" Utils.PlayTabletAnim = function() local ped = PlayerPedId() -- Incarca animatia RequestAnimDict(animDict) while not HasAnimDictLoaded(animDict) do Wait(10) end -- Joaca animatia (flag 49 = loop + upper body + secondary) TaskPlayAnim(ped, animDict, animName, 2.0, -2.0, -1, 49, 0, false, false, false) -- Creeaza prop tableta local model = GetHashKey("prop_rv_tablet") RequestModel(model) while not HasModelLoaded(model) do Wait(10) end local coords = GetEntityCoords(ped) tabletProp = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) -- Ataseaza la mana dreapta (bone 60309) AttachEntityToEntity(tabletProp, ped, GetPedBoneIndex(ped, 60309), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, true, true, false, true, 1, true) SetModelAsNoLongerNeeded(model) RemoveAnimDict(animDict) end Utils.StopTabletAnim = function() local ped = PlayerPedId() -- Opreste animatia ClearPedTasks(ped) -- Sterge prop-ul if tabletProp and DoesEntityExist(tabletProp) then DeleteEntity(tabletProp) tabletProp = nil end end Utils.AddEntityToTarget = function(entity) exports[Config.TargetSystem]:AddTargetEntity(entity, { options = { { icon = "fas fa-briefcase", label = _L("Interaction.Open"), action = function() Utils.PlayTabletAnim() Utils.ToggleNUI(true) end, }, }, distance = 1.5 }) end -- Opreste animatia cand se inchide meniul (safety net) -- Monitorizeza NUI focus — cand se pierde, opreste animatia -- Seteaza state bag pentru text bubble vizibil de toti jucatorii CreateThread(function() local wasOpen = false while true do Wait(500) local nuiFocused = IsNuiFocused() if wasOpen and not nuiFocused then -- Meniul tocmai s-a inchis Utils.StopTabletAnim() LocalPlayer.state:set("browsingJobs", false, true) wasOpen = false elseif nuiFocused and tabletProp and DoesEntityExist(tabletProp) then if not wasOpen then LocalPlayer.state:set("bubbleText", "Se uita la locuri de munca...", true) LocalPlayer.state:set("bubbleIcon", "💼", true) LocalPlayer.state:set("browsingJobs", true, true) end wasOpen = true end end end) -- Deseneaza text bubble deasupra jucatorilor care cauta joburi -- Vizibil pentru toti jucatorii din apropiere CreateThread(function() while true do Wait(0) local myPed = PlayerPedId() local myCoords = GetEntityCoords(myPed) for _, playerId in ipairs(GetActivePlayers()) do local targetPed = GetPlayerPed(playerId) local state = Player(GetPlayerServerId(playerId)).state if state and state.browsingJobs then local pedCoords = GetEntityCoords(targetPed) local dist = #(myCoords - pedCoords) if dist < 15.0 then local headBone = GetPedBoneCoords(targetPed, 31086, 0.0, 0.0, 0.0) -- SKEL_Head local bubbleText = state.bubbleText or "Se uita la locuri de munca..." local bubbleIcon = state.bubbleIcon or "" Utils.DrawJobBubble(headBone.x, headBone.y, headBone.z + 0.35, bubbleIcon .. " " .. bubbleText) end end end end end) -- Deseneaza text bubble stilizat deasupra capului Utils.DrawJobBubble = function(x, y, z, text) local onScreen, _x, _y = World3dToScreen2d(x, y, z) if onScreen then local camCoords = GetGameplayCamCoords() local dist = #(vec3(x, y, z) - camCoords) local scale = (1 / dist) * 2 local fov = (1 / GetGameplayCamFov()) * 100 scale = scale * fov -- Limiteaza scala if scale > 0.4 then scale = 0.4 end if scale < 0.15 then scale = 0.15 end -- Background box SetTextScale(0.0, scale * 0.5) SetTextFont(4) SetTextProportional(true) SetTextColour(255, 255, 255, 245) SetTextDropshadow(1, 0, 0, 0, 200) SetTextEdge(2, 0, 0, 0, 180) SetTextDropShadow() SetTextOutline() SetTextEntry("STRING") SetTextCentre(true) AddTextComponentString(text) DrawText(_x, _y) end end