local isOpen = false local cam = nil local authDone = false -- A slow drift over the city gives the glass something to sit on. local CAM_POS = vector3(-1030.0, -2730.0, 320.0) local CAM_LOOK = vector3(-75.0, -815.0, 220.0) local SPAWN_POS = vector3(195.17, -889.36, 30.69) local SPAWN_HDG = 145.0 local function startCamera() cam = CreateCamWithParams('DEFAULT_SCRIPTED_CAMERA', CAM_POS.x, CAM_POS.y, CAM_POS.z, 0.0, 0.0, 0.0, 55.0, false, 0) PointCamAtCoord(cam, CAM_LOOK.x, CAM_LOOK.y, CAM_LOOK.z) SetCamActive(cam, true) RenderScriptCams(true, false, 0, true, true) -- Drift the camera so the backdrop is never a frozen still. CreateThread(function() local angle = 0.0 while cam and DoesCamExist(cam) and not authDone do angle = angle + 0.02 local radius = 260.0 SetCamCoord(cam, CAM_POS.x + math.cos(math.rad(angle)) * radius, CAM_POS.y + math.sin(math.rad(angle)) * radius, CAM_POS.z) PointCamAtCoord(cam, CAM_LOOK.x, CAM_LOOK.y, CAM_LOOK.z) Wait(20) end end) end local function stopCamera() if cam and DoesCamExist(cam) then RenderScriptCams(false, true, 900, true, true) DestroyCam(cam, false) cam = nil end end local function openAuth() isOpen = true SetNuiFocus(true, true) SendNUIMessage({ action = 'open' }) DoScreenFadeIn(600) end local function closeAuth() isOpen = false SetNuiFocus(false, false) SendNUIMessage({ action = 'close' }) end -- Keep the unauthenticated player parked and invisible behind the glass. CreateThread(function() while not authDone do local ped = PlayerPedId() SetEntityVisible(ped, false, false) SetEntityCollision(ped, false, false) FreezeEntityPosition(ped, true) SetPlayerInvincible(PlayerId(), true) DisableAllControlActions(0) Wait(0) end end) -- Any map resource can re-enable auto spawn when it starts, so hold the gate -- shut every time that happens until the player actually has an identity. AddEventHandler('onClientMapStart', function() if not authDone then exports.spawnmanager:setAutoSpawn(false) end end) CreateThread(function() -- Take spawning away from spawnmanager until the player has an identity. exports.spawnmanager:setAutoSpawn(false) DoScreenFadeOut(0) while not NetworkIsSessionStarted() do Wait(100) end Wait(500) startCamera() openAuth() end) -- The account is known; fiverp-characters owns everything from here — the -- slot screen, the appearance creator and the spawn itself. Auth only has to -- fade out, release its camera and step aside. local function enterCity() authDone = true closeAuth() DoScreenFadeOut(500) Wait(600) stopCamera() exports.spawnmanager:setAutoSpawn(false) TriggerEvent('fiverp-chars:begin') end -- ------------------------------------------------------------- NUI callbacks RegisterNUICallback('registerAccount', function(data, cb) TriggerServerEvent('fiverp-auth:register:account', data) cb({}) end) RegisterNUICallback('registerIdentity', function(data, cb) TriggerServerEvent('fiverp-auth:register:identity', data) cb({}) end) RegisterNUICallback('resumeIdentity', function(data, cb) TriggerServerEvent('fiverp-auth:resume:identity', data) cb({}) end) RegisterNUICallback('login', function(data, cb) TriggerServerEvent('fiverp-auth:login', data) cb({}) end) -- --------------------------------------------------------------- server said RegisterNetEvent('fiverp-auth:register:accountResult', function(result) SendNUIMessage({ action = 'accountResult', payload = result }) end) RegisterNetEvent('fiverp-auth:register:identityResult', function(result) SendNUIMessage({ action = 'identityResult', payload = result }) if result.ok then CreateThread(function() Wait(1600) -- let the permit finish stamping before the fade enterCity(result.firstName, result.lastName) end) end end) RegisterNetEvent('fiverp-auth:loginResult', function(result) SendNUIMessage({ action = 'loginResult', payload = result }) if result.ok and not result.needsIdentity then CreateThread(function() Wait(1200) enterCity(result.firstName, result.lastName) end) end end)