--[[ Main Client File]] client = { framework = shared.GetFrameworkObject(), load = false, uiLoad = false, isBusy = false, tabletInHand = nil, } --[[ require ]] require 'modules.bridge.client' local Utils = require 'modules.utils.client' local Target = require 'modules.target.client' --[[ functions ]] function addTargetOptions() for key, model in pairs(Config.AtmModels) do Target.AddModel(model, { [1] = { label = locale('rope'), name = locale('rope'), icon = 'fa-solid fa-link', distance = 1.25, canInteract = function() return not client.isBusy end, onSelect = function(data) local entity = type(data) == 'table' and data.entity or data Rope.CreateAtmRope(entity, model) end }, [2] = { label = locale('explode'), name = locale('explode'), icon = 'fa-solid fa-explosion', distance = 1.25, canInteract = function() return not client.isBusy end, onSelect = function(data) local entity = type(data) == 'table' and data.entity or data Explode.PlantBomb(entity, model) end }, }) end end function removeTargetOptions() Target.RemoveModel(Config.AtmModels, { locale('rope'), locale('explode'), locale('hacking') }) end function clearClient() Rope.Clear() Explode.Clear() Hack.Clear() removeTargetOptions() if client.tabletInHand then client.removeTabletFromPlayer() end client.setBusy(false, 'clearClient') end function client.setHeadingToObject(model) local ped = cache.ped local pedCoords = GetEntityCoords(ped) local object = GetClosestObjectOfType(pedCoords.x, pedCoords.y, pedCoords.z, 2.0, model, false, false, false) if object and DoesEntityExist(object) then local objCoords = GetEntityCoords(object) local heading = GetHeadingFromVector_2d(objCoords.x - pedCoords.x, objCoords.y - pedCoords.y) SetEntityHeading(ped, heading) Citizen.Wait(100) end end --[[ @ ]] local function hideFrame() client.SendReactMessage('ui:setVisible', false) SetNuiFocus(false, false) Hack.DeletePhone() end function client.setBusy(state, key) if not forced and client.isBusy == state then return end Utils.debug(('client busy state is changed. New value: %s by %s'):format(state, key)) client.isBusy = state end ---Sends message to the ReactUI. ---@param action string ---@param data any function client.SendReactMessage(action, data) SendNUIMessage({ action = action, data = data }) end --- Prepare the frontend and send the data function client.SetupUI() if client.uiLoad then return end local defaultLocale = GetConvar('ox:locale', 'en') client.SendReactMessage('ui:setupUI', { setLocale = lib.loadJson(('locales.%s'):format(defaultLocale)).ui, }) end function client.onPlayerLoad(isLoggedIn) client.load = isLoggedIn if isLoggedIn then addTargetOptions() else clearClient() end end --- Starts the client resource. function client.StartResource() if client.IsPlayerLoaded() then client.onPlayerLoad(true) end end --[[ End @ ]] --[[ functions ]] function client.giveTabletToPlayer() if client.tabletInHand then return end local playerPedId = cache.ped local tabletModel = 'hei_prop_dlc_tablet' local holdTabletAnim = { dict = 'amb@world_human_clipboard@male@idle_a', name = 'idle_a' } local tabletObject = Utils.CreateObject(tabletModel, GetEntityCoords(playerPedId), nil, true, true, false) client.tabletInHand = tabletObject AttachEntityToEntity(tabletObject, playerPedId, GetPedBoneIndex(playerPedId, 60309), 0.0, 0.0, 0.02, 0.0, 120.0, 0.0, true, true, false, false, 2, true) lib.playAnim(playerPedId, holdTabletAnim.dict, holdTabletAnim.name) end function client.givePhoneToPlayer() if client.tabletInHand then return end local playerPedId = cache.ped local phoneModel = 'prop_npc_phone_02' local holdPhoneAnim = { dict = 'cellphone@', name = 'cellphone_text_in' } local tabletObject = Utils.CreateObject(phoneModel, GetEntityCoords(playerPedId), nil, true, true, false) client.tabletInHand = tabletObject AttachEntityToEntity(tabletObject, playerPedId, GetPedBoneIndex(playerPedId, 28422), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1, 1, 0, 0, 2, 1) lib.playAnim(playerPedId, holdPhoneAnim.dict, holdPhoneAnim.name, 3.0, 3.0, -1, 50) end function client.removeTabletFromPlayer() local tabletObject = client.tabletInHand if tabletObject and DoesEntityExist(tabletObject) then SetEntityAsMissionEntity(tabletObject, true, true) DeleteEntity(tabletObject) end client.tabletInHand = nil ClearPedTasks(cache.ped) end --[[ @ ]] RegisterNUICallback('nui:loadUI', function(_, resultCallback) resultCallback(true) client.SetupUI() end) RegisterNUICallback('nui:onLoadUI', function(_, resultCallback) resultCallback(true) client.uiLoad = true end) RegisterNUICallback('nui:hideFrame', function(_, resultCallback) hideFrame() resultCallback(true) end) AddEventHandler('onResourceStart', function(resource) if resource == shared.resource then Citizen.Wait(2000) client.StartResource() end end) AddEventHandler('onResourceStop', function(resource) if resource == shared.resource then client.onPlayerLoad(false) Utils.HideTextUI() end end) --[[ End @ ]]