-- Prevent running if menu is disabled if not TX_MENU_ENABLED then return end -- ============================================= -- This file is for all main page logic not controlled in its -- own file (mainly simpler logic) -- ============================================= --[[ NUI CALLBACKS ]] -- Data is a object with x, y, z RegisterSecureNuiCallback('tpToCoords', function(data, cb) debugPrint(json.encode(data)) TriggerServerEvent('txsv:req:tpToCoords', data.x + 0.0, data.y + 0.0, data.z + 0.0) cb({}) end) RegisterCommand('txAdmin:menu:tpToCoords', function() if not menuIsAccessible then return end if not DoesPlayerHavePerm(menuPermissions, 'players.teleport') then return sendSnackbarMessage('error', 'nui_menu.misc.no_perms', true) end toggleMenuVisibility(true) SetNuiFocus(true, true) sendMenuMessage('openTeleportCoordsDialog', {}) end) local function reqTpToWaypoint(_, cb) TriggerServerEvent('txsv:req:tpToWaypoint') if cb then cb({}) end end RegisterSecureNuiCallback('tpToWaypoint', reqTpToWaypoint) RegisterCommand('txAdmin:menu:tpToWaypoint', function() if not menuIsAccessible then return end if not DoesPlayerHavePerm(menuPermissions, 'players.teleport') then return sendSnackbarMessage('error', 'nui_menu.misc.no_perms', true) end reqTpToWaypoint() end) local function reqTpBack(_, cb) if lastTpCoords then TriggerServerEvent('txsv:req:tpToCoords', lastTpCoords.x, lastTpCoords.y, lastTpCoords.z) else sendSnackbarMessage('error', 'nui_menu.page_main.teleport.back.error', true) end if cb then cb({}) end end RegisterSecureNuiCallback('tpBack', reqTpBack) RegisterCommand('txAdmin:menu:tpBack', function() if not menuIsAccessible then return end if not DoesPlayerHavePerm(menuPermissions, 'players.teleport') then return sendSnackbarMessage('error', 'nui_menu.misc.no_perms', true) end reqTpBack() end) RegisterSecureNuiCallback('tpToPlayer', function(data, cb) TriggerServerEvent('txsv:req:tpToPlayer', tonumber(data.id)) cb({}) end) RegisterSecureNuiCallback('summonPlayer', function(data, cb) TriggerServerEvent('txsv:req:bringPlayer', tonumber(data.id)) cb({}) end) RegisterSecureNuiCallback('copyCurrentCoords', function(_, cb) local ped = PlayerPedId() local curCoords = GetEntityCoords(ped) local currHeading = GetEntityHeading(ped) -- We will cut coords to 4 decimal points local stringCoords = ('%.4f, %.4f, %.4f, %.4f'):format(curCoords.x, curCoords.y, curCoords.z, currHeading) cb({ coords = stringCoords }) end) RegisterSecureNuiCallback('clearArea', function(radius, cb) TriggerServerEvent('txsv:req:clearArea', radius) cb({}) end) RegisterCommand('txAdmin:menu:clearArea', function() if not menuIsAccessible then return end if not DoesPlayerHavePerm(menuPermissions, 'menu.clear_area') then return sendSnackbarMessage('error', 'nui_menu.misc.no_perms', true) end toggleMenuVisibility(true) SetNuiFocus(true, true) sendMenuMessage('openClearAreaDialog', {}) end) -- [[ Spawn weapon (only in dev, for now) ]] RegisterSecureNuiCallback('spawnWeapon', function(weapon, cb) if not TX_DEBUG_MODE then return end debugPrint("Spawning weapon: " .. weapon) GiveWeaponToPed(PlayerPedId(), weapon, 500, false, true) cb({}) end) RegisterSecureNuiCallback('healPlayer', function(data, cb) TriggerServerEvent('txsv:req:healPlayer', tonumber(data.id)) cb({}) end) local healSelfMessage = 0 local function reqHealMyself(_, cb) local msg = 'nui_menu.page_main.heal.myself.success_'..healSelfMessage sendSnackbarMessage('success', msg, true) healSelfMessage = healSelfMessage + 1 if healSelfMessage > 3 then healSelfMessage = 0 end TriggerServerEvent('txsv:req:healMyself') if cb then cb({}) end end RegisterSecureNuiCallback('healMyself', reqHealMyself) RegisterCommand('txAdmin:menu:healMyself', function() if not menuIsAccessible then return end if not DoesPlayerHavePerm(menuPermissions, 'players.heal') then return sendSnackbarMessage('error', 'nui_menu.misc.no_perms', true) end reqHealMyself() end) RegisterSecureNuiCallback('healAllPlayers', function(_, cb) TriggerServerEvent('txsv:req:healEveryone') cb({}) end) -- Data will be an object with a message attribute RegisterSecureNuiCallback('sendAnnouncement', function(data, cb) TriggerServerEvent('txsv:req:sendAnnouncement', data.message) cb({}) end) --[[ EVENT HANDLERS + FUNCTION LOGIC ]] local function handleTpNormally(x, y, z) local ped = PlayerPedId() local veh = GetVehiclePedIsIn(ped, false) local horse if IS_FIVEM then SetPedCoordsKeepVehicle(ped, x, y, 100.0) else if IsPedOnMount(ped) then horse = GetMount(ped) SetEntityCoords(horse, x, y, 100.0, false, false, false, false) FreezeEntityPosition(horse, true) end SetEntityCoords(ped, x, y, 100.0, false, false, false, false) end --Prepare vehicle if veh > 0 then if IS_REDM then SetVehicleCanBreak(veh, false) SetVehicleWheelsCanBreak(veh, false) SetEntityCollision(veh, false, false) SetEntityCoords(veh, x, y, 100.0, false, false, false, false) SetPedIntoVehicle(ped, veh, -1) end FreezeEntityPosition(veh, true) else FreezeEntityPosition(ped, true) end while IsEntityWaitingForWorldCollision(ped) do debugPrint("waiting for collision...") Wait(100) end -- Automatically calculate ground Z if z == 0 then local _finalZ local DELAY = 500 for i = 1, 5 do if _finalZ ~= nil then break end debugPrint("Z calc attempt #" .. i .. " (" .. (i * DELAY) .. "ms)") _finalZ = FindZForCoords(x, y) if _z == nil then debugPrint("Didn't resolve! Trying again in " .. DELAY) Wait(DELAY) end end if _finalZ ~= nil then z = _finalZ end end -- Teleport to targert ped = PlayerPedId() --update ped id if IS_FIVEM then SetPedCoordsKeepVehicle(ped, x, y, z) else if horse then SetEntityCoords(horse, x, y, z + 0.5, false, false, false, false) FreezeEntityPosition(horse, false) end SetEntityCoords(ped, x, y, z + 0.5, false, false, false, false) end -- handle vehicle teleport if veh > 0 then veh = GetVehiclePedIsIn(ped, false) --update veh id SetEntityAlpha(veh, 125) SetEntityCoords(veh, x, y, z + 0.5, false, false, false, false) SetPedIntoVehicle(ped, veh, -1) SetVehicleOnGroundProperly(veh) SetEntityCollision(veh, true, true) FreezeEntityPosition(veh, false) CreateThread(function() Wait(2000) ResetEntityAlpha(veh) SetVehicleCanBreak(veh, true) SetVehicleWheelsCanBreak(veh, true) end) else FreezeEntityPosition(ped, false) end -- point camera to the ped direction if IS_FIVEM then SetGameplayCamRelativeHeading(0) else Citizen.InvokeNative(0x14F3947318CA8AD2, 0.0, 0.0) -- SetThirdPersonCamRelativeHeadingLimitsThisUpdate end end local function handleTpForFreecam(x, y, z) debugPrint("Handling TP for freecam") local ped = PlayerPedId() -- As we allow the freecam to have a vehicle attached. We need to make -- sure to teleport this as well local veh = GetVehiclePedIsIn(ped, false) debugPrint('Freecam has vehicle attached: ' .. tostring(veh)) if veh and veh > 0 then SetEntityCoords(veh, x, y, z) end SetFreecamPosition(x, y, z) end local function teleportToCoords(coords) if type(coords) ~= 'vector3' then return debugPrint("^1Invalid coords") end local x = coords[1] local y = coords[2] local z = coords[3] local ped = PlayerPedId() DoScreenFadeOut(500) while not IsScreenFadedOut() do Wait(0) end if IsFreecamActive() then local curCamPos = GetFreecamPosition() lastTpCoords = curCamPos handleTpForFreecam(x, y, z) else lastTpCoords = GetEntityCoords(ped) handleTpNormally(x, y, z) end DoScreenFadeIn(500) end --- Teleport the player to the coordinates ---@param x number ---@param y number ---@param z number RegisterNetEvent('txcl:tpToCoords', function(x, y, z) teleportToCoords(vec3(x, y, z)) return sendSnackbarMessage('success', 'nui_menu.page_main.teleport.generic_success', true) end) -- Teleport to the current waypoint RegisterNetEvent('txcl:tpToWaypoint', function() if not IsWaypointActive() then return sendSnackbarMessage('error', 'nui_menu.page_main.teleport.waypoint.error', true) end local destCoords if IS_FIVEM then local waypoint = GetFirstBlipInfoId(GetWaypointBlipEnumId()) destCoords = GetBlipInfoIdCoord(waypoint) else destCoords = GetWaypointCoords() end teleportToCoords(vec3(destCoords.x, destCoords.y, 0)) sendSnackbarMessage('success', 'nui_menu.page_main.teleport.generic_success', true) end) RegisterNetEvent('txcl:clearArea', function(radius) sendSnackbarMessage( 'success', 'nui_menu.page_main.clear_area.dialog_success', true, { radius = radius } ) if IS_REDM then return end local curCoords = GetEntityCoords(PlayerPedId()) local radiusToFloat = radius + 0.0 debugPrint(('Radius to clear %d'):format(radius)) -- WTF?: User reports that this native actually clears dead peds compared to -- ClearArea? Weird considering Gottfried updated this native from _CLEAR_AREA_OF_EVERYTHING -- after found nativedb info. Maybe needs research lmao? ClearAreaLeaveVehicleHealth(curCoords.x, curCoords.y, curCoords.z, radiusToFloat, false, false, false, false, false) end)